A full-stack web dashboard for managing AWS resources exposed through LocalStack. Built with Fastify, React, and the AWS SDK v3.
LocalStack Explorer provides an AWS Console-like experience for your local development environment, letting you browse, create, and manage resources without leaving the browser.
| Service | Status | Description |
|---|---|---|
| S3 | Fully implemented | Buckets, objects, upload/download |
| SQS | Fully implemented | Queue management, message operations, queue attributes, purge |
| SNS | Fully implemented | Topics, subscriptions, publish, tags, filter policies |
| IAM | Fully implemented | Users, groups, managed/inline policies, access keys, versioning |
| CloudFormation | Fully implemented | Stack CRUD, update, template editor, events, cross-service links |
| DynamoDB | Fully implemented | Table management, create, list, detail views |
- Node.js >= 20
- pnpm >= 9
- Docker (for LocalStack)
git clone https://github.com/fgiova/localstack-explorer.git
cd localstack-explorer
pnpm installdocker compose up -dThis starts LocalStack with all required services (S3, SQS, SNS, IAM, CloudFormation, DynamoDB) on http://localhost:4566.
Start both backend and frontend in parallel:
pnpm devOr start them separately:
# Terminal 1 — Backend (http://localhost:3001)
cd packages/backend && pnpm dev
# Terminal 2 — Frontend (http://localhost:5173)
cd packages/frontend && pnpm devThe frontend dev server proxies /api requests to the backend automatically.
pnpm buildBuild backend and frontend together, then run with a single node command. The backend serves the frontend static files automatically.
pnpm run build:standalone
pnpm start
# → http://localhost:3001A pre-built multi-arch image is available on Docker Hub:
docker run -d -p 3001:3001 \
-e LOCALSTACK_ENDPOINT=http://host.docker.internal:4566 \
fgiova/localstack-explorer:latestThen open http://localhost:3001.
To build the Docker image locally for multiple platforms and push to a registry:
docker buildx build --push --platform linux/arm64,linux/amd64 --tag yourname/localstack-explorer:latest .Package the application as a native desktop app:
pnpm run build:desktopOutput in packages/desktop/out/ (DMG on macOS, AppImage on Linux, NSIS on Windows).
pnpm testThe backend uses env-schema for environment variable validation with .env file support.
| Variable | Default | Description |
|---|---|---|
PORT |
3001 |
Backend server port |
LOCALSTACK_ENDPOINT |
http://localhost:4566 |
Default LocalStack endpoint URL |
LOCALSTACK_REGION |
us-east-1 |
Default AWS region for LocalStack clients |
ENABLED_SERVICES |
s3,sqs,sns,iam,cloudformation,dynamodb |
Comma-separated list of enabled services |
Create a .env file in packages/backend/ to override defaults.
Region and endpoint can be changed at runtime from the UI without restarting the server:
- Region selector — a dropdown in the header lists all 30 AWS regions. The change takes effect immediately for all subsequent API calls.
- Endpoint modal — click the connection indicator (server icon) in the header to enter a custom LocalStack endpoint. The modal tests connectivity against
GET /api/health(which returns{ connected, error? }) and only allows saving after a successful test. - Auto-detection — if the configured endpoint is unreachable at startup, the endpoint modal opens automatically so you can enter a valid URL.
- Server defaults — on first load (before the user has ever changed settings), the frontend fetches
defaultEndpointanddefaultRegionfromGET /api/servicesand applies them. This means the values ofLOCALSTACK_ENDPOINTandLOCALSTACK_REGIONconfigured on the server are always reflected in the UI for new sessions.
Each browser tab maintains its own endpoint and region settings (persisted in localStorage), so you can connect multiple tabs to different LocalStack instances simultaneously. Once a user explicitly changes endpoint or region via the UI, those values take precedence over server defaults.
By default, only a subset of services is enabled. You can control which services are available by setting the ENABLED_SERVICES environment variable to a comma-separated list of service names:
# Enable only S3 and SQS
ENABLED_SERVICES=s3,sqs
# Enable all available services
ENABLED_SERVICES=s3,sqs,sns,iam,cloudformation,dynamodbAvailable service names: s3, sqs, sns, iam, cloudformation, dynamodb.
When a service is disabled:
- Its backend API routes are not registered (requests return 404)
- Its card is hidden from the dashboard
- Its entry is removed from the sidebar navigation
The frontend fetches the list of enabled services from the GET /api/services endpoint at startup and filters the UI accordingly.
localstack-explorer/
├── bundle/ # tsup bundle output (build:bundle)
├── packages/
│ ├── backend/ # Fastify API server
│ │ └── src/
│ │ ├── index.ts # Entry point (autoload plugins, serves frontend)
│ │ ├── bundle.ts # Bundle entry point (explicit plugin imports)
│ │ ├── config.ts # env-schema configuration
│ │ ├── health.ts # LocalStack connectivity check
│ │ ├── aws/ # AWS SDK client factories & cache
│ │ ├── plugins/ # Auto-loaded plugins (one per service)
│ │ │ ├── s3/ # Complete implementation
│ │ │ ├── sqs/ # Complete implementation
│ │ │ ├── sns/ # Complete implementation
│ │ │ ├── iam/ # Complete implementation
│ │ │ ├── cloudformation/ # Complete implementation
│ │ │ └── dynamodb/ # Complete implementation
│ │ └── shared/ # Error handling, shared types
│ └── frontend/ # React SPA
│ └── src/
│ ├── routes/ # TanStack Router file-based routes
│ ├── components/ # UI components (Shadcn/ui + custom)
│ │ └── settings/ # Region selector, endpoint modal
│ ├── api/ # TanStack Query hooks
│ ├── stores/ # Zustand state management (app + config)
│ └── lib/ # Utilities and API client
│ └── desktop/ # Electron desktop app
│ ├── main.cjs # Electron main process
│ ├── electron-builder.json
│ └── scripts/ # Build helpers
├── docker-compose.yaml # LocalStack dev environment
├── package.json # Workspace root
├── pnpm-workspace.yaml
└── tsconfig.base.json # Shared TypeScript config
| Layer | Technology |
|---|---|
| Monorepo | pnpm workspaces |
| Backend | Fastify 5, TypeScript |
| Frontend | React 19, Vite 6, TypeScript |
| UI Components | Shadcn/ui, Radix UI, Tailwind CSS 4 |
| State Management | Zustand 5 |
| Data Fetching | TanStack Query 5 |
| Routing | TanStack Router 1 (file-based) |
| AWS SDK | @aws-sdk/* v3 |
| Validation | TypeBox 1 |
| Config | env-schema (with dotenv) |
| Plugin Loading | @fastify/autoload |
| Static Serving | @fastify/static (standalone/bundle mode) |
| Bundler | tsup (single-file CJS bundle) |
| Desktop | Electron 33, electron-builder |
| Testing | Vitest, React Testing Library |
- S3 Service Guide — Complete reference for S3 operations: buckets, objects, upload/download, and API endpoints.
- SQS Service Guide — Complete reference for SQS operations: queue management, message send/receive/delete, queue attributes, and purge.
- SNS Service Guide — Complete reference for SNS operations: topics, subscriptions, publish (single/batch), filter policies, and tags.
- IAM Service Guide — Complete reference for IAM operations: users, groups, managed/inline policies, access keys, policy versioning, and cascading deletes.
- CloudFormation Service Guide — Complete reference for CloudFormation operations: stack CRUD, update, template editor, events timeline, and cross-service resource navigation.
- DynamoDB Service Guide — Complete reference for DynamoDB operations: table management, creation, listing, and detail views.
- Adding New Services — Step-by-step guide to implement a new AWS service following the established plugin pattern.
- Architecture — System design, backend plugin pattern, frontend data flow, and project conventions.
- Development Guide — Local setup, testing, coding standards, and contribution workflow.
MIT