A Python boto3-style wrapper for AWS SDK v3 in Node.js — designed to make AWS S3 operations simple, elegant, and familiar for developers who love the boto3 experience.
- Built on top of the official AWS SDK for JavaScript v3
- Automatic credential loading (from environment variables or ~/.aws/credentials)
- Modern, Promise-based async/await API
- Simple pre-signed URL generation
- Optional debug mode for easy inspection
npm install @shubhvora/boto3-js
You can configure the client in two ways. The AWS SDK will automatically detect credentials from environment variables (AWS_ACCESS_KEY_ID, etc.) or your shared credentials file.
Usage
You can directly set your AWS region and credentials in code:
import { setup, boto3, AWSService } from "@shubhvora/boto3-js";
// Configure global AWS credentials
setup({
region: "ap-south-1",
accessKeyId: "YOUR_AWS_ACCESS_KEY_ID",
secretAccessKey: "YOUR_AWS_SECRET_ACCESS_KEY",
});
// Initialize S3 client
const s3 = boto3(AWSService.S3);
// Use your client
await s3.upload("my-bucket", "file.txt", "./local/file.txt");
Great for dynamic runtime configuration or testing multiple environments.
Create a .env file in your project root:
AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY
AWS_REGION=ap-south-1
Then simply import boto3-js — no manual setup required:
import { boto3, AWSService } from "@shubhvora/boto3-js";
// Initialize S3 client (reads from .env automatically)
const s3 = boto3(AWSService.S3);
await s3.upload("my-bucket", "file.txt", "./local/file.txt");
Ideal for projects that store secrets in environment files.
Use loadEnv() if your .env file is somewhere else:
import { loadEnv, boto3, AWSService } from "@shubhvora/boto3-js";
// Load environment variables from any location
loadEnv("/configs/aws/.env.prod");
// Initialize S3 client
const s3 = boto3(AWSService.S3);
await s3.upload("my-bucket", "file.txt", "./local/file.txt");
Useful for multi-environment setups or non-root .env files.
.env.example
AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY
AWS_REGION=us-east-1
const buckets = await s3.listBuckets();
console.log("Buckets:", buckets);
await s3.createBucket("my-awesome-new-bucket-12345");
console.log("Bucket created!");
const objects = await s3.listObjects("my-awesome-new-bucket-12345");
console.log("Objects:", objects);
import fs from "fs";
const fileContent = fs.readFileSync("path/to/your/file.txt");
await s3.uploadFile("my-awesome-new-bucket-12345", "file.txt", fileContent);
console.log("File uploaded\!");
const content = await s3.downloadFile("my-awesome-new-bucket-12345", "file.txt");
console.log("File content:", content);
await s3.deleteObject("my-awesome-new-bucket-12345", "file.txt");
console.log("Object deleted\!");
await s3.copyObject(
"my-awesome-new-bucket-12345",
"file.txt",
"my-backup-bucket",
"file-copy.txt"
);
console.log("Object copied\!");
// Get a URL that expires in 10 minutes (600 seconds)
const url = await s3.getObjectURL("my-awesome-new-bucket-12345", "file.txt", 600);
console.log("Signed URL:", url);
Method | Description | Example |
---|---|---|
listBuckets() | Lists all S3 buckets in your account. | await s3.listBuckets() |
createBucket(name) | Creates a new bucket. | await s3.createBucket("my-bucket") |
deleteBucket(name) | Deletes an existing bucket. | await s3.deleteBucket("my-bucket") |
listObjects(bucket) | Lists all objects in a given bucket. | await s3.listObjects("my-bucket") |
uploadFile(bucket, key, body) | Uploads a file (string, Buffer, or Stream). | await s3.uploadFile("bucket", "key", data) |
downloadFile(bucket, key) | Downloads file contents as a string. | await s3.downloadFile("bucket", "key") |
deleteObject(bucket, key) | Deletes a specific object. | await s3.deleteObject("bucket", "key") |
copyObject(srcBucket, srcKey, destBucket, destKey) | Copies an object between locations. | await s3.copyObject("src", "a.txt", "dest", "b.txt") |
getObjectURL(bucket, key, expiresIn) | Generates a temporary, pre-signed download URL. | await s3.getObjectURL("bucket", "key", 3600) |
This creates a new table with a partition key. A sort key is optional.
await db.createTable({
tableName: "Users",
partitionKey: "id",
});
console.log("Table 'Users' created\!");
putItem will create a new item or overwrite an existing item with the same key.
await db.putItem("Users", {
id: { S: "1" },
name: { S: "Vortex" },
role: { S: "Master" },
});
console.log("Item added\!");
Retrieve a single item by its key.
const user = await db.getItem("Users", { id: { S: "1" } });
console.log("Retrieved item:", user);
Atomically update an item's attributes without overwriting the entire item.
const updatedUser = await db.updateItem(
"Users",
{ id: { S: "1" } }, // Key of the item to update
{ role: { S: "Legend" } } // Attributes to update
);
console.log("Updated item attributes:", updatedUser);
A scan operation reads every item in a table. Use with caution on large tables.
const allUsers = await db.scan("Users", {});
console.log("All items in table:", allUsers);
More efficient than scan, query finds items based on primary key values.
const params = {
KeyConditionExpression: "id = :idVal",
ExpressionAttributeValues: {
":idVal": { S: "1" },
},
};
const results = await db.query("Users", params);
console.log("Query results:", results);
await db.deleteItem("Users", { id: { S: "1" } });
console.log("Item deleted\!");
Method | Description | Example |
---|---|---|
createTable({tableName, partitionKey, ...}) | Creates a new DynamoDB table. | await db.createTable({ tableName: "T", partitionKey: "id" }) |
putItem(table, item) | Creates or replaces an entire item. | await db.putItem("T", { id: {S: "1"}, ... }) |
getItem(table, key) | Retrieves an item by its primary key. | await db.getItem("T", { id: {S: "1"} }) |
updateItem(table, key, updates) | Modifies specific attributes of an existing item. | await db.updateItem("T", { id: {S: "1"} }, { name: {S: "New"} }) |
deleteItem(table, key) | Deletes a single item by its primary key. | await db.deleteItem("T", { id: {S: "1"} }) |
query(table, params) | Finds items using only primary key attribute values. | await db.query("T", { KeyConditionExpression: "id = :v", ... }) |
scan(table, params) | Reads every item in a table or secondary index. | await db.scan("T", {}) |
batchWrite(items) | Puts or deletes multiple items in one or more tables (up to 25 items). | await db.batchWrite({ 'Table1': [...] }) |
transactWrite(transactions) | An all-or-nothing operation for writing to multiple items within tables. | await db.transactWrite([{ Put: {...} }, { Update: {...} }]) |
The Secrets Manager client provides a simple interface for the complete lifecycle of your secrets, including creation, retrieval, replication, and deletion.
First, initialize the client:
JavaScript
import { boto3, AWSService } from "@shubhvora/boto3-js";
// Initialize Secrets Manager client
const sm = boto3(AWSService.SECRETMANAGER);
putSecret will create a new secret or update the value of an existing one. It automatically handles JSON stringification.
JavaScript
const secretName = "my-app/database-credentials";
const secretValue = { user: "admin", pass: "P@ssw0rd123\!" };
await sm.putSecret(secretName, secretValue);
console.log(\`Secret '${secretName}' created/updated\!\`);
Retrieve and parse the secret's value. It automatically parses JSON strings back into objects.
JavaScript
const credentials = await sm.getSecret("my-app/database-credentials");
console.log("Retrieved username:", credentials.user);
Get metadata about a secret, such as its ARN, tags, and replication status.
JavaScript
const details = await sm.describeSecret("my-app/database-credentials");
console.log("Secret ARN:", details.ARN);
Easily replicate a secret to other AWS regions for multi-region applications.
JavaScript
await sm.replicateSecret("my-app/database-credentials", \["us-west-2", "eu-central-1"\]);
console.log("Secret replication initiated\!");
Retrieve a paginated list of all secrets in the configured region.
JavaScript
const secrets = await sm.listSecrets();
console.log(\`Found ${secrets.SecretList.length} secrets.\`);
This function permanently deletes a secret. It's designed to automatically find and remove any replicas first, simplifying the cleanup process.
JavaScript
await sm.deleteSecretPermanent("my-app/database-credentials");
console.log("Secret and all its replicas have been permanently deleted\!");
Method | Description | Example |
---|---|---|
getSecret(name) | Retrieves the secret value, auto-parsing JSON. | await sm.getSecret("my/secret") |
putSecret(name, value) | Creates a new secret or updates an existing one. | await sm.putSecret("my/secret", {k: "v"}) |
describeSecret(name) | Gets a secret's metadata, tags, and replication info. | await sm.describeSecret("my/secret") |
listSecrets(limit?) | Lists all secrets in the region. | await sm.listSecrets() |
listVersions(name) | Lists all versions of a specific secret. | await sm.listVersions("my/secret") |
updateSecret(name, params) | Performs a raw update using AWS SDK parameters. | await sm.updateSecret("my/secret", {Desc: "..."}) |
tagSecret(name, tags) | Adds key-value tags to a secret. | await sm.tagSecret("my/secret", [{K:"a", V:"b"}]) |
untagSecret(name, tagKeys) | Removes tags from a secret by their keys. | await sm.untagSecret("my/secret", ["KeyA"]) |
replicateSecret(name, regions) | Replicates a secret to one or more AWS regions. | await sm.replicateSecret("my/secret", ["us-west-2"]) |
rotateSecret(name, lambdaArn?) | Initiates rotation for a secret. | await sm.rotateSecret("my/secret") |
cancelRotation(name) | Disables automatic rotation for a secret. | await sm.cancelRotation("my/secret") |
deleteSecretPermanent(name) | Permanently deletes a secret and its replicas. | await sm.deleteSecretPermanent("my/secret") |
deleteSecretWithRecovery(name, days?) | Deletes a secret with a recovery window (default 7 days). | await sm.deleteSecretWithRecovery("my/secret", 15) |
restoreSecret(name) | Restores a secret that was deleted with a recovery window. | await sm.restoreSecret("my/secret") |
All methods are wrapped in try...catch blocks and will throw a descriptive error on failure.
try {
const data = await s3.downloadFile("non-existent-bucket", "imaginary-file.txt");
} catch (err) {
// Example Error: "S3 downloadFile(non-existent-bucket, imaginary-file.txt) failed: The specified bucket does not exist"
console.error(err.message);
}
Pull requests are welcome! If you'd like to contribute, please fork the repository and open a pull request.
- Fork the repo
- Create a new branch: git checkout -b feature/my-new-feature
- Commit your changes: git commit -m "Add my new feature"
- Push to your fork: git push origin feature/my-new-feature
- Open a Pull Request on GitHub
This project is licensed under the MIT License.
Made with ❤️ by Shubh Vora