---
title: "DynamoDB CRUD in Node.js with the AWS SDK v3 DocumentClient"
lang: "en"
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/post/nodejs-dynamodb-crud-aws-sdk-v3
---

![Blog post image for AWS DynamoDB CRUD Operations in Node.js with the AWS SDK v3 - A practical Node.js snippet covering DynamoDB put, get, update, delete, and query operations using the modern AWS SDK v3. Includes the DocumentClient pattern, single-table design basics, and error handling.](/_astro/hero.CceR-orf_ZIzOWU.webp)

[Home](/)›[Codesnippets](/codesnippets)›[All Categories](/codesnippets/categories)›[Nodejs](/codesnippets/categories/nodejs)

Codesnippets

[Next in NodejsNode.js Environment Variable Validation with Zod at Startup](/codesnippets/post/nodejs-env-validation-zod-startup)

[Nodejs](/codesnippets/categories/nodejs)[Aws](/codesnippets/categories/aws)[Database](/codesnippets/categories/database)[Typescript](/codesnippets/typescript)

# AWS DynamoDB CRUD Operations in Node.js with the AWS SDK v3

[Mohammad Abu Mattar](/authors/mohammad-abu-mattar)Published: 05 Aug 2026Updated: 05 Aug 202607 Mins read09 Mins listen

[Markdown for AI(opens in a new tab)](/post/nodejs-dynamodb-crud-aws-sdk-v3/index.md "Open the plain-Markdown version of this page, for pasting into an AI tool")

TL;DR

A practical Node.js snippet covering DynamoDB put, get, update, delete, and query operations using the modern AWS SDK v3. Includes the DocumentClient pattern, single-table design basics, and error handling.

Series

[Node.js Snippets](/series/nodejs-snippets)1/1

All posts in this series (1)

Code Snippets1

1.  [AWS DynamoDB CRUD Operations in Node.js with the AWS SDK v3You are here](/codesnippets/post/nodejs-dynamodb-crud-aws-sdk-v3)

### AWS DynamoDB CRUD Operations in Node.js with the AWS SDK v3

Contents

[The Problem](#the-problem)[Why raw attribute maps hurt](#why-raw-attribute-maps-hurt)[The real-world impact](#the-real-world-impact)[The Solution](#the-solution)[Script Implementation](#script-implementation)[Setup and the DocumentClient](#setup-and-the-documentclient)[Create and read: put and get](#create-and-read-put-and-get)[Update and delete safely](#update-and-delete-safely)[Query by key instead of scanning](#query-by-key-instead-of-scanning)[Entry point with error handling](#entry-point-with-error-handling)[Usage and Benefits](#usage-and-benefits)[Real invocations](#real-invocations)[Tuning for single-table design](#tuning-for-single-table-design)[Comparison](#comparison)[Frequently Asked Questions](#frequently-asked-questions)[References](#references)

**Quick Tip**

Wrap the low-level DynamoDB client in a `DynamoDBDocumentClient` so you pass plain JavaScript objects in and get plain objects back, then guard your writes with `ConditionExpression` and read by key with `QueryCommand`.

## [The Problem](#the-problem)

**The Problem**

The low-level DynamoDB API doesn’t speak JavaScript. Every value has to be wrapped in a typed attribute map, so a simple `{ id: "42", count: 3 }` turns into `{ id: { S: "42" }, count: { N: "3" } }` on the way in, and you have to unwrap all of it on the way out. Write that marshalling by hand across a codebase and it becomes a steady drip of `ValidationException` errors and off-by-one type bugs.

### [Why raw attribute maps hurt](#why-raw-attribute-maps-hurt)

The attribute-map format leaks into every call site. You can’t just hand DynamoDB the object your app already has, you first translate it, then translate the response back, and you repeat that boilerplate for put, get, update, and query. It’s easy to send a number as a string or forget a nested map, and DynamoDB rejects the whole request rather than coercing anything for you.

### [The real-world impact](#the-real-world-impact)

That friction shows up as slow feature work and brittle data access. New team members trip over the `{ S: ... }` wrappers, updates accidentally overwrite fields they never meant to touch, and someone reaches for `Scan` because it “just works,” quietly reading the entire table on every call. The result is code that’s harder to review and a bill that grows faster than the data.

## [The Solution](#the-solution)

**The Fix**

Use the AWS SDK v3 `DynamoDBDocumentClient`. It wraps the base `DynamoDBClient` and handles marshalling in both directions, so your CRUD code deals in plain objects. Pair it with a single table, address items by their partition and sort keys, use `UpdateCommand` to change only the fields you name, and add a `ConditionExpression` when a write must not clobber existing data.

**TL;DR**

-   Wrap `DynamoDBClient` in `DynamoDBDocumentClient` so you never touch raw attribute maps.
-   Use `PutCommand`, `GetCommand`, `UpdateCommand`, and `DeleteCommand` for CRUD, with `ConditionExpression` to keep writes safe.
-   Read with `QueryCommand` on the partition key instead of scanning the whole table.

## [Script Implementation](#script-implementation)

### [Setup and the DocumentClient](#setup-and-the-documentclient)

Create the base client once, wrap it in a `DynamoDBDocumentClient`, and turn on the marshalling options that smooth over DynamoDB’s quirks. Reuse this single instance across your app so connections get pooled.

dynamo.ts

```
1// dynamo.ts - CRUD helpers for a single DynamoDB table with the AWS SDK v3.2import {DynamoDBClient} from '@aws-sdk/client-dynamodb';3import {4  DynamoDBDocumentClient,5  PutCommand,6  GetCommand,7  UpdateCommand,8  DeleteCommand,9  QueryCommand,10} from '@aws-sdk/lib-dynamodb';11
12const TABLE_NAME = process.env.TABLE_NAME ?? 'AppTable';13
14// One low-level client for the process; region comes from the environment.15const baseClient = new DynamoDBClient({});16
17// The DocumentClient marshals plain JS objects to/from attribute maps.18export const ddb = DynamoDBDocumentClient.from(baseClient, {19  marshallOptions: {20    // Drop undefined fields instead of erroring on them.21    removeUndefinedValues: true,22    // Store empty strings and sets as-is rather than converting to null.23    convertEmptyValues: false,24  },25});26
27// A tiny item shape for the examples: single-table keys plus data.28export interface User {29  pk: string; // partition key, e.g. "USER#42"30  sk: string; // sort key, e.g. "PROFILE"31  name: string;32  email: string;33  loginCount?: number;34}
```

### [Create and read: put and get](#create-and-read-put-and-get)

`PutCommand` writes a whole item, overwriting any existing item with the same key. `GetCommand` fetches one item by its full primary key and returns a plain object, or `undefined` when nothing matches.

```
1// Create or overwrite an item. Pass the object as-is, no attribute maps.2export async function putUser(user: User): Promise<void> {3  await ddb.send(4    new PutCommand({5      TableName: TABLE_NAME,6      Item: user,7    }),8  );9}10
11// Fetch a single item by its partition + sort key.12export async function getUser(13  pk: string,14  sk: string,15): Promise<User | undefined> {16  const {Item} = await ddb.send(17    new GetCommand({18      TableName: TABLE_NAME,19      Key: {pk, sk},20    }),21  );22  // Item is already a plain object, cast it to the known shape.23  return Item as User | undefined;24}
```

### [Update and delete safely](#update-and-delete-safely)

`UpdateCommand` changes only the fields you name in the `UpdateExpression`, so you never overwrite the rest of the item. The `ConditionExpression` makes the update fail loudly if the item doesn’t already exist, which stops accidental “upserts.” `DeleteCommand` removes an item by key.

```
1// Update named fields only, and require that the item already exists.2export async function bumpLoginCount(pk: string, sk: string): Promise<User> {3  const {Attributes} = await ddb.send(4    new UpdateCommand({5      TableName: TABLE_NAME,6      Key: {pk, sk},7      // ADD creates loginCount at 1 if missing, otherwise increments it.8      UpdateExpression: 'ADD loginCount :one',9      ConditionExpression: 'attribute_exists(pk)',10      ExpressionAttributeValues: {':one': 1},11      ReturnValues: 'ALL_NEW',12    }),13  );14  return Attributes as User;15}16
17// Delete an item by key. Idempotent: deleting a missing key is a no-op.18export async function deleteUser(pk: string, sk: string): Promise<void> {19  await ddb.send(20    new DeleteCommand({21      TableName: TABLE_NAME,22      Key: {pk, sk},23    }),24  );25}
```

### [Query by key instead of scanning](#query-by-key-instead-of-scanning)

`QueryCommand` reads every item that shares a partition key, optionally narrowed by the sort key. This is the read you want almost every time, it touches only the matching items instead of the whole table the way `Scan` does.

```
1// Fetch every item under one partition key, e.g. all records for a user.2export async function queryByUser(pk: string): Promise<User[]> {3  const items: User[] = [];4  let ExclusiveStartKey: Record<string, unknown> | undefined;5
6  // Loop to follow pagination until DynamoDB stops returning a cursor.7  do {8    const page = await ddb.send(9      new QueryCommand({10        TableName: TABLE_NAME,11        KeyConditionExpression: 'pk = :pk',12        ExpressionAttributeValues: {':pk': pk},13        ExclusiveStartKey,14      }),15    );16    items.push(...((page.Items ?? []) as User[]));17    ExclusiveStartKey = page.LastEvaluatedKey;18  } while (ExclusiveStartKey);19
20  return items;21}
```

### [Entry point with error handling](#entry-point-with-error-handling)

Tie the helpers together in a small demo and catch the one error you actually expect: a failed `ConditionExpression`. DynamoDB reports it as a `ConditionalCheckFailedException`, which you handle rather than crash on.

```
1import {ConditionalCheckFailedException} from '@aws-sdk/client-dynamodb';2
3async function main(): Promise<void> {4  const key = {pk: 'USER#42', sk: 'PROFILE'};5
6  await putUser({...key, name: 'Ada', email: 'ada@example.com'});7  console.log('created:', await getUser(key.pk, key.sk));8
9  try {10    const updated = await bumpLoginCount(key.pk, key.sk);11    console.log('login count is now', updated.loginCount);12  } catch (err) {13    if (err instanceof ConditionalCheckFailedException) {14      console.error('update skipped: that user does not exist yet');15    } else {16      throw err; // Anything else is unexpected, let it surface.17    }18  }19
20  console.log('all records:', await queryByUser(key.pk));21  await deleteUser(key.pk, key.sk);22}23
24main().catch((err) => {25  console.error(err);26  process.exit(1);27});
```

## [Usage and Benefits](#usage-and-benefits)

**Why This Helps**

The `DocumentClient` deletes an entire category of bugs by letting you work in plain objects, and the CRUD helpers give every call site the same safe pattern: named updates, conditional writes, and key-based reads. You stop hand-writing attribute maps, stop accidentally overwriting fields, and stop reaching for `Scan` when a `Query` is right there.

### [Real invocations](#real-invocations)

Terminal window

```
1# Install the SDK v3 packages.2npm install @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb3
4# Set the table and region, then run the compiled script.5export AWS_REGION=us-east-16export TABLE_NAME=AppTable7node dynamo.js8
9# Or run the TypeScript directly during development.10npx tsx dynamo.ts
```

### [Tuning for single-table design](#tuning-for-single-table-design)

The `pk`/`sk` pair is the heart of single-table design: you overload one table with many item types by encoding the type into the key. A user profile might use `pk = "USER#42"`, `sk = "PROFILE"`, while their orders use the same `pk` with `sk = "ORDER#1001"`. One `QueryCommand` on `USER#42` then pulls the profile and every order in a single call.

```
1// Same partition key, different sort keys, one query returns them all.2await putUser({3  pk: 'USER#42',4  sk: 'PROFILE',5  name: 'Ada',6  email: 'ada@example.com',7});8await putUser({pk: 'USER#42', sk: 'ORDER#1001', name: 'order', email: '-'});9
10// begins_with narrows a query to just the orders under this user.11const orders = await ddb.send(12  new QueryCommand({13    TableName: TABLE_NAME,14    KeyConditionExpression: 'pk = :pk AND begins_with(sk, :prefix)',15    ExpressionAttributeValues: {':pk': 'USER#42', ':prefix': 'ORDER#'},16  }),17);
```

## [Comparison](#comparison)

How the SDK v3 `DocumentClient` stacks up against the other common ways to talk to DynamoDB from Node.js.

Approach

Marshalling

API style

Maintained

Best for

SDK v3 `DynamoDBDocumentClient`

Automatic

Command objects

Yes

New Node.js apps on the SDK v3

SDK v3 low-level `DynamoDBClient`

Manual maps

Command objects

Yes

Fine-grained control, edge cases

SDK v2 `DynamoDB.DocumentClient`

Automatic

Method calls

Maintenance only

Legacy code still on v2

An ORM/ODM like Dynamoose

Automatic + schema

Model methods

Yes

Teams wanting model abstractions

The low-level client is worth dropping to only when you need something the `DocumentClient` doesn’t expose. For everyday CRUD, the document client’s automatic marshalling is the reason it exists.

## [Frequently Asked Questions](#frequently-asked-questions)

`DynamoDBClient` is the low-level client: it speaks DynamoDB’s native format, so every value is a typed attribute map like `{ S: "text" }` or `{ N: "3" }`. `DynamoDBDocumentClient` wraps it and adds marshalling in both directions, so you pass and receive plain JavaScript objects. You still create the base client, then build the document client from it with `DynamoDBDocumentClient.from(baseClient)`. Use the document client for CRUD and drop to the base client only for the rare feature it doesn’t cover.

`Query` reads only the items that share a partition key, using the index directly, so it stays fast and cheap as the table grows. `Scan` reads every item in the table and then filters, which means its cost and latency scale with the whole dataset, not with the rows you want. Design your keys so the reads you need are `Query` calls. Keep `Scan` for genuine full-table jobs like exports or backfills, and even then paginate it.

Use `UpdateCommand` with an `UpdateExpression` that names only the fields you’re changing, such as `SET #n = :name` or `ADD loginCount :one`. That leaves every other attribute on the item untouched. `PutCommand`, by contrast, replaces the entire item, so any field you don’t include is dropped. When a name collides with a DynamoDB reserved word, alias it through `ExpressionAttributeNames` (the `#n` above) so the expression still parses.

A `ConditionExpression` makes a write happen only if the condition holds, and fail otherwise. `attribute_exists(pk)` blocks an update from silently creating a new item, `attribute_not_exists(pk)` blocks a put from overwriting an existing one, and a version check like `version = :expected` gives you optimistic locking. When the condition fails, DynamoDB throws `ConditionalCheckFailedException`, which you catch and handle instead of letting a bad write through.

DynamoDB returns at most 1 MB of data per `Query` or `Scan`. When there’s more, the response includes a `LastEvaluatedKey` cursor. Pass it back as `ExclusiveStartKey` on the next call and loop until the response stops returning one, which is exactly what `queryByUser` does. Skip the loop and you silently read only the first page, a bug that hides until your data crosses the 1 MB boundary in production.

Only for code that already runs on it. The SDK v2 is in maintenance mode, so new work should use v3, which is modular (you install just `@aws-sdk/client-dynamodb` and `@aws-sdk/lib-dynamodb`), tree-shakeable, and actively developed. The v3 `DynamoDBDocumentClient` gives you the same automatic marshalling the v2 `DocumentClient` did, just with the command-object API. Migrate when you can, but there’s no need to rush a rewrite that works.

## [References](#references)

-   [AWS SDK v3: @aws-sdk/lib-dynamodb (DocumentClient)](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-lib-dynamodb/)
-   [AWS SDK v3: @aws-sdk/client-dynamodb](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-dynamodb/)
-   [DynamoDB Developer Guide: Query operations](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html)
-   [DynamoDB Developer Guide: Condition expressions](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)
-   [DynamoDB Developer Guide: Single-table design](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html)
-   [AWS SDK for JavaScript v3 Developer Guide](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html)

Was this useful?

## Tags

[#DynamoDB](/codesnippets/tags/dynamodb)[#Node.js](/codesnippets/tags/nodejs)[#AWS SDK v3](/codesnippets/tags/aws-sdk-v3)[#TypeScript](/codesnippets/tags/typescript)[#CRUD](/codesnippets/tags/crud)[#DocumentClient](/codesnippets/tags/documentclient)

## Share

[Facebook](https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3 "Share on Facebook")[Twitter](https://twitter.com/intent/tweet/?text=AWS%20DynamoDB%20CRUD%20Operations%20in%20Node.js%20with%20the%20AWS%20SDK%20v3&url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3 "Share on Twitter")[LinkedIn](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3&title=AWS%20DynamoDB%20CRUD%20Operations%20in%20Node.js%20with%20the%20AWS%20SDK%20v3&summary=A%20practical%20Node.js%20snippet%20covering%20DynamoDB%20put%2C%20get%2C%20update%2C%20delete%2C%20and%20query%20operations%20using%20the%20modern%20AWS%20SDK%20v3.%20Includes%20the%20DocumentClient%20pattern%2C%20single-table%20design%20basics%2C%20and%20error%20handling.&source=https://mkabumattar.com "Share on LinkedIn")[WhatsApp](https://wa.me/?text=AWS%20DynamoDB%20CRUD%20Operations%20in%20Node.js%20with%20the%20AWS%20SDK%20v3%20https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3 "Share on WhatsApp")[Telegram](https://t.me/share/url?url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3&text=AWS%20DynamoDB%20CRUD%20Operations%20in%20Node.js%20with%20the%20AWS%20SDK%20v3 "Share on Telegram")[Reddit](https://www.reddit.com/submit?url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3&title=AWS%20DynamoDB%20CRUD%20Operations%20in%20Node.js%20with%20the%20AWS%20SDK%20v3 "Share on Reddit")[Hacker News](http://news.ycombinator.com/submitlink?u=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3&t=AWS%20DynamoDB%20CRUD%20Operations%20in%20Node.js%20with%20the%20AWS%20SDK%20v3 "Share on Hacker News")[Pinterest](https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3&media=&description=A%20practical%20Node.js%20snippet%20covering%20DynamoDB%20put%2C%20get%2C%20update%2C%20delete%2C%20and%20query%20operations%20using%20the%20modern%20AWS%20SDK%20v3.%20Includes%20the%20DocumentClient%20pattern%2C%20single-table%20design%20basics%2C%20and%20error%20handling. "Share on Pinterest")[Email](<mailto:?subject=AWS%20DynamoDB%20CRUD%20Operations%20in%20Node.js%20with%20the%20AWS%20SDK%20v3&body=Check out this article: https%3A%2F%2Fmkabumattar.com%2Fcodesnippets%2Fpost%2Fnodejs-dynamodb-crud-aws-sdk-v3>)

## Comments

## You might also enjoy

More posts on similar topics

[![Node.js Environment Variable Validation with Zod at Startup](/_astro/hero.DEQ8-R8h_1M1QX3.webp)](/codesnippets/post/nodejs-env-validation-zod-startup)

## [Node.js Environment Variable Validation with Zod at Startup](/codesnippets/post/nodejs-env-validation-zod-startup)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Nodejs](/codesnippets/categories/nodejs)
-   [Typescript](/codesnippets/categories/typescript)
-   [Backend](/codesnippets/categories/backend)

Most Node.js apps treat process.env like a trusted friend. You reach into it whenever you need a value, assume the key is there, assume it's spelled right, and assume the string is actually the type

[#Node.js](/codesnippets/tags/nodejs)[#TypeScript](/codesnippets/tags/typescript)[#Zod](/codesnippets/tags/zod)+5 tags

[read more](/codesnippets/post/nodejs-env-validation-zod-startup)

[![AWS Secrets Manager](/_astro/hero.BIDl4oI2_Z1yJEXf.webp)](/codesnippets/post/nodejs-aws-secrets-manager)

## [AWS Secrets Manager](/codesnippets/post/nodejs-aws-secrets-manager)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Aws](/codesnippets/categories/aws)
-   [Devops](/codesnippets/categories/devops)

Loading secrets in a Node.js app without exposing them If you're still storing API keys or database credentials in .env files or hardcoding them into your codebase, it's time for a better appro

[#NodeJS](/codesnippets/tags/nodejs)[#TypeScript](/codesnippets/tags/typescript)[#AWS](/codesnippets/tags/aws)+3 tags

[read more](/codesnippets/post/nodejs-aws-secrets-manager)

[![AWS EC2 Instance Management with Boto3: Start, Stop, and Query Instances](/_astro/hero.PnHlvJay_ZkFqWG.webp)](/codesnippets/post/aws-ec2-instance-management-boto3-python)

## [AWS EC2 Instance Management with Boto3: Start, Stop, and Query Instances](/codesnippets/post/aws-ec2-instance-management-boto3-python)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Cloud](/codesnippets/categories/cloud)
-   [Aws](/codesnippets/categories/aws)
-   [Devops](/codesnippets/categories/devops)
-   [Automation](/codesnippets/categories/automation)

If you've ever spent 20 minutes clicking through the AWS Console just to stop a handful of dev instances, you already know the pain. It's tedious, it doesn't scale, and one wrong click can ruin your a

[#AWS](/codesnippets/tags/aws)[#EC2](/codesnippets/tags/ec2)[#Boto3](/codesnippets/tags/boto3)+6 tags

[read more](/codesnippets/post/aws-ec2-instance-management-boto3-python)

[![PostgreSQL Query Optimization: Indexes, EXPLAIN ANALYZE & Execution Plans](/_astro/hero.WD7Zwlat_2dqoYO.webp)](/codesnippets/post/postgresql-query-optimization-indexes-explain)

## [PostgreSQL Query Optimization: Indexes, EXPLAIN ANALYZE & Execution Plans](/codesnippets/post/postgresql-query-optimization-indexes-explain)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Database](/codesnippets/categories/database)
-   [Performance](/codesnippets/categories/performance)

Need to optimize slow PostgreSQL queries? Use EXPLAIN ANALYZE and targeted indexing. Slow database queries kill application performance. Most developers don't know where the actual bottleneck is,

[#PostgreSQL](/codesnippets/tags/postgresql)[#QueryOptimization](/codesnippets/tags/queryoptimization)[#Indexes](/codesnippets/tags/indexes)+4 tags

[read more](/codesnippets/post/postgresql-query-optimization-indexes-explain)

[![Check S3 Bucket Existence](/_astro/hero.CWiO4GWV_1YUYTb.webp)](/codesnippets/post/bash-s3-bucket-exists)

## [Check S3 Bucket Existence](/codesnippets/post/bash-s3-bucket-exists)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Aws](/codesnippets/categories/aws)
-   [Shell scripting](/codesnippets/categories/shell-scripting)
-   [Devops](/codesnippets/categories/devops)

Quick Tip Don't let your deployment blow up because of a missing S3 bucket. This Bash script lets you check if a bucket exists before anything fails. The Problem Missing bucket failure

[#Bash](/codesnippets/tags/bash)[#AWS](/codesnippets/tags/aws)[#DevOps](/codesnippets/tags/devops)+3 tags

[read more](/codesnippets/post/bash-s3-bucket-exists)

[![List S3 Buckets](/_astro/hero.BsiJ6hry_1X9XLn.webp)](/codesnippets/post/python-list-s3-buckets)

## [List S3 Buckets](/codesnippets/post/python-list-s3-buckets)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   [Aws](/codesnippets/categories/aws)
-   [Python](/codesnippets/categories/python)
-   [Devops](/codesnippets/categories/devops)

Overview Multi-profile S3 management Ever juggled multiple AWS accounts and needed a quick S3 bucket inventory across all of them? This Python script handles it. Use case Perfect for or

[#Python](/codesnippets/tags/python)[#Boto3](/codesnippets/tags/boto3)[#AWS](/codesnippets/tags/aws)+5 tags

[read more](/codesnippets/post/python-list-s3-buckets)

6 related posts
