An interactive SvelteKit demo powered by the AWS Strands Agents SDK (@strands-agents/sdk). The app runs a model-driven, multi-step agent loop with calculator and live weather tools. Built with Svelte 5, styled with Tailwind CSS, and optimized for secure server-side processing.
Repository: github.com/xxdxxd/strands-agent
Use an environment file or container environment variables rather than hardcoding credentials in the UI or source code. This keeps API keys out of the client bundle and version control.
The application reads OPENAI_API_KEY and OPENAI_BASE_URL from the server environment. In local development and production (npm run start), the server loads a root .env file automatically via the dotenv package (see src/lib/server/env.ts and src/hooks.server.ts).
- Locate the
.env.exampletemplate in the root directory. - Duplicate it and rename it to
.env:cp .env.example .env
- Open
.envand specify your credentials:# Your OpenRouter or OpenAI API Key OPENAI_API_KEY="your_actual_api_key" # Base URL (defaults to OpenRouter if not specified) OPENAI_BASE_URL="https://openrouter.ai/api/v1"
If no server-side key is configured, you can still enter an API key in the left sidebar at runtime. The /api/health endpoint reports whether a host key is present.
Follow these steps to run the app directly on Ubuntu without Docker.
Ensure standard system tools and Node.js v20.x or higher are installed.
# Update Ubuntu package lists
sudo apt update && sudo apt upgrade -y
# Install curl, git, and build essentials
sudo apt install -y curl git build-essential
# Install Node.js LTS (v20.x) via NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# Verify installation versions
node -v
npm -vNavigate to the project root directory:
cd /path/to/strandsAgentDemo-mainnpm installNote: The project includes a root
.npmrcwithlegacy-peer-deps=trueso@strands-agents/sdkinstalls cleanly alongside its optional peer dependencies.
cp .env.example .envEdit .env and set your API credentials.
This starts SvelteKit’s unified dev server for both the UI and API routes:
npm run devOpen the app at:
- Dev URL:
http://localhost:3000
To use a different port:
npm run dev -- --port 5173Compile the client and server bundles with SvelteKit’s Node adapter, then start the production server:
npm run build
npm run startOpen the app at:
- Production URL:
http://localhost:3000
For production, export environment variables in your shell or pass them through your process manager. The Node adapter reads PORT (default 3000) and HOST (default 0.0.0.0).
The included Dockerfile builds a production image on Ubuntu 22.04 with Node.js 20, compiles the SvelteKit app, and runs the Node adapter output from build/index.js.
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# Add Docker's official GPG key and repository
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Optional: run Docker without sudo
sudo usermod -aG docker "$USER"
newgrp docker
docker --versionFrom the project root:
cd /path/to/strandsAgentDemo-main
docker build -t strands-agent .Map container port 3000 to your host and provide API credentials as environment variables:
docker run -d \
--name strands-agent-container \
-p 3000:3000 \
-e OPENAI_API_KEY="your-actual-api-key-here" \
-e OPENAI_BASE_URL="https://openrouter.ai/api/v1" \
strands-agentIf you omit OPENAI_API_KEY, the UI still loads, but you must enter a key in the sidebar before chat requests will work.
Open:
http://localhost:3000
Check container health:
curl http://localhost:3000/api/health# Follow application logs
docker logs -f strands-agent-container
# Stop and remove the container
docker stop strands-agent-container
docker rm strands-agent-containerInstead of passing secrets on the command line, mount a local .env file:
docker run -d \
--name strands-agent-container \
-p 3000:3000 \
--env-file .env \
strands-agent- Strands Agents SDK: Server-side orchestration in
src/lib/server/agent.tsusesAgent,OpenAIModel, andagent.stream()with a 6-turn limit. Tools are declared insrc/lib/server/strands-tools.tsvia Strandstool()+ Zod schemas. - OpenAI-compatible models: Works with OpenRouter or any OpenAI-compatible API (
OPENAI_BASE_URL,OPENAI_API_KEY). - SvelteKit server routes: All model calls run inside
/src/routes/api/*so API keys never reach the browser. - Reasoning trail UI: The chat timeline renders streamed Strands events (model turns, tool calls, tool output, errors) in
ReasoningView.svelte. - Svelte 5 runes: Uses
$state,$derived, and$effectfor reactive UI updates and chat session persistence inlocalStorage. - Git leak protection:
.gitignoreexcludes.envfiles from commits.
If you notice that npm run build or the workspace compilation takes several seconds or minutes, this is entirely normal and expected. Here is why:
- Virtualized Container Resource Constraints: In online sandboxes and cloud environments, resources (CPU, RAM, Disk I/O) are shared across multiple tenants. Node compilation is highly CPU-bound and Disk I/O-intensive, which slows down during high container concurrency.
- SvelteKit Double Compile Phase: During
vite build, Vite compiles two separate bundles: a client-side bundle (for the browser UI) and a server-side bundle (for SSR/node-adapter runtime handling). - Tailwind compilation & post-processing: The Tailwind CSS engine scans the project for classes, transforms them, and optimizes them into a single CSS payload for compression.
- Adapter Optimization: SvelteKit's Node adapter post-processes the compiled bundles into a standalone entrypoint in the
build/directory.