Skip to content

thunder-so/thunder

Repository files navigation

thunder

Version License

Build full-stack apps on your own AWS.

Thunder is a CDK library for deploying modern web applications on AWS. One library to rule them all: Static SPAs, Lambda Functions, Containers on Fargate and EC2, and Serverless Full-stack Frameworks.

Table of Contents

Features

  • Constructs: One-line deployment for Static, Lambda, Fargate, EC2, Serverless, and framework-specific constructs.
  • VPC Link Pattern: Easily connect your compute resources to a shared VPC.
  • High-Performance Serving: Pre-configured CloudFront distributions with OAC, security headers, and edge optimizations.
  • Built-in CI/CD: Optional AWS CodePipeline integration with GitHub support.

Supported Frameworks & Patterns

Quick Start

1. Install

bun add @thunder-so/thunder --development

2. Configure

Create a stack file (e.g., stack/dev.ts):

import { Cdk, Static, type StaticProps } from "@thunder-so/thunder";

const myApp: StaticProps = {
  env: {
    account: "123456789012",
    region: "us-east-1",
  },
  application: "myapp",
  service: "web",
  environment: "prod",

  rootDir: ".",
  outputDir: "dist",
};

new Static(
  new Cdk.App(),
  `${myApp.application}-${myApp.service}-${myApp.environment}-stack`,
  myApp,
);

3. Deploy

npx cdk deploy --app "npx tsx stack/dev.ts" --profile default

Stacks

Static

Deploy static websites to S3 with CloudFront CDN and Route53 DNS.

Best for: Static sites, SPAs, JAMstack applications

AWS Resources:

Example:

import { Cdk, Static, type StaticProps } from "@thunder-so/thunder";

const config: StaticProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "web",
  environment: "prod",
  rootDir: ".",
  outputDir: "dist",

  // Optional: Custom domain
  domain: "example.com",
  globalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",

  // Optional: Lambda@Edge for redirects/headers/rewrites
  redirects: [{ source: "/old", destination: "/" }],
  rewrites: [{ source: "/old", destination: "/new" }],
  headers: [{ path: "/*", name: "X-Custom-Header", value: "value" }],
};

new Static(new Cdk.App(), "myapp-web-prod-stack", config);

Lambda

Deploy serverless functions with API Gateway and optional Lambda Function URL.

Best for: Serverless APIs, microservices, event-driven applications

AWS Resources:

Example:

import { Cdk, Lambda, type LambdaProps } from "@thunder-so/thunder";

const config: LambdaProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "api",
  environment: "prod",
  rootDir: ".",

  functionProps: {
    runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
    architecture: Cdk.aws_lambda.Architecture.ARM_64,
    codeDir: "src",
    handler: "index.handler",
    memorySize: 512,
    timeout: 30,
    url: true, // Enable function URL
    keepWarm: true, // Prevent cold starts
    variables: [{ NODE_ENV: "production" }],
    secrets: [{ key: "DATABASE_URL", resource: "arn:aws:secretsmanager:..." }],
  },

  // Optional: Custom domain
  domain: "api.example.com",
  regionalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",
};

new Lambda(new Cdk.App(), "myapp-api-prod-stack", config);

Fargate

Deploy containerized applications on ECS Fargate with Application Load Balancer and CloudFront.

Best for: Containerized web applications, microservices, long-running processes

AWS Resources:

Example:

import { Cdk, Fargate, type FargateProps } from "@thunder-so/thunder";

const config: FargateProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "api",
  environment: "prod",
  rootDir: ".",

  serviceProps: {
    architecture: Cdk.aws_ecs.CpuArchitecture.ARM64,
    desiredCount: 2,
    cpu: 512, // 0.5 vCPU
    memorySize: 1024, // 1 GB
    port: 3000,
    healthCheckPath: "/health",
    variables: [{ NODE_ENV: "production" }],
    dockerFile: "Dockerfile",
  },

  // Optional: Custom domain
  domain: "api.example.com",
  globalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",
};

new Fargate(new Cdk.App(), "myapp-api-prod-stack", config);

EC2

Deploy Docker containers on EC2 instances with Elastic IP for simple, cost-effective hosting.

Best for: Single-instance applications, development environments, simple Docker deployments

AWS Resources:

Example:

import { Cdk, Ec2, type Ec2Props } from "@thunder-so/thunder";

const config: Ec2Props = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "api",
  environment: "prod",
  rootDir: ".",

  serviceProps: {
    instanceType: "t3.micro",
    port: 3000,
    authorizedKeys: ["ssh-rsa AAAAB3... user@example.com"],
    dockerFile: "Dockerfile",
    variables: [{ NODE_ENV: "production" }],
  },

  // Optional: Custom domain with SSL
  domain: "api.example.com",
  hostedZoneId: "Z123456789",
  acmeEmail: "admin@example.com", // For Let's Encrypt
};

new Ec2(new Cdk.App(), "myapp-api-prod-stack", config);

Serverless Frameworks

Deploy modern meta-frameworks as serverless applications with unified infrastructure - Lambda for server-side rendering and S3 for static assets, all behind CloudFront.

Best for: Full-stack applications with server-side rendering, API routes, and static asset optimization

Supported Frameworks: Nuxt, Astro, TanStack Start, SvelteKit, Solid Start, AnalogJS, or any Vite/Nitro-based framework using the generic Serverless construct.

AWS Resources:

Supported Frameworks:

  • TanStack Start - Type-safe full-stack React framework
  • Nuxt - Vue-based full-stack framework
  • Astro - Content-focused web framework with islands architecture
  • SvelteKit - Svelte-based full-stack framework
  • Solid Start - SolidJS full-stack framework
  • AnalogJS - Angular-based full-stack framework

TanStack Start

Example:

import {
  Cdk,
  TanStackStart,
  type TanStackStartProps,
} from "@thunder-so/thunder";

const config: TanStackStartProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "web",
  environment: "prod",
  rootDir: ".",

  serverProps: {
    runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
    architecture: Cdk.aws_lambda.Architecture.ARM_64,
    memorySize: 1792,
    timeout: 10,
    keepWarm: true,
    variables: [{ NODE_ENV: "production" }],
  },

  // Optional: Custom domain
  domain: "myapp.com",
  globalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",
};

new TanStackStart(new Cdk.App(), "myapp-web-prod-stack", config);

Nuxt

Example:

import { Cdk, Nuxt, type NuxtProps } from "@thunder-so/thunder";

const config: NuxtProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "web",
  environment: "prod",
  rootDir: ".",

  serverProps: {
    runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
    architecture: Cdk.aws_lambda.Architecture.ARM_64,
    memorySize: 1792,
    timeout: 10,
    keepWarm: true,
    streaming: true,
    variables: [{ NODE_ENV: "production" }],
    secrets: [{ key: "DATABASE_URL", resource: "arn:aws:secretsmanager:..." }],
  },

  // Optional: Custom domain
  domain: "myapp.com",
  globalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",
};

new Nuxt(new Cdk.App(), "myapp-web-prod-stack", config);

Astro

Example:

import { Cdk, Astro, type AstroProps } from "@thunder-so/thunder";

const config: AstroProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "web",
  environment: "prod",
  rootDir: ".",

  serverProps: {
    runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
    architecture: Cdk.aws_lambda.Architecture.ARM_64,
    memorySize: 1024,
    timeout: 10,
    keepWarm: true,
    variables: [{ NODE_ENV: "production" }],
  },

  // Optional: Custom domain
  domain: "myapp.com",
  globalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",
};

new Astro(new Cdk.App(), "myapp-web-prod-stack", config);

SvelteKit

Example:

import { Cdk, SvelteKit, type SvelteKitProps } from "@thunder-so/thunder";

const config: SvelteKitProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "web",
  environment: "prod",
  rootDir: ".",

  serverProps: {
    runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
    architecture: Cdk.aws_lambda.Architecture.ARM_64,
    memorySize: 1024,
    timeout: 10,
    keepWarm: true,
    variables: [{ NODE_ENV: "production" }],
  },

  // Optional: Custom domain
  domain: "myapp.com",
  globalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",
};

new SvelteKit(new Cdk.App(), "myapp-web-prod-stack", config);

Solid Start

Example:

import { Cdk, SolidStart, type SolidStartProps } from "@thunder-so/thunder";

const config: SolidStartProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "web",
  environment: "prod",
  rootDir: ".",

  serverProps: {
    runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
    architecture: Cdk.aws_lambda.Architecture.ARM_64,
    memorySize: 1024,
    timeout: 10,
    keepWarm: true,
    variables: [{ NODE_ENV: "production" }],
  },

  // Optional: Custom domain
  domain: "myapp.com",
  globalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",
};

new SolidStart(new Cdk.App(), "myapp-web-prod-stack", config);

AnalogJS

Example:

import { Cdk, AnalogJS, type AnalogJSProps } from "@thunder-so/thunder";

const config: AnalogJSProps = {
  env: { account: "123456789012", region: "us-east-1" },
  application: "myapp",
  service: "web",
  environment: "prod",
  rootDir: ".",

  serverProps: {
    runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
    architecture: Cdk.aws_lambda.Architecture.ARM_64,
    memorySize: 1024,
    timeout: 10,
    keepWarm: true,
    variables: [{ NODE_ENV: "production" }],
  },

  // Optional: Custom domain
  domain: "myapp.com",
  globalCertificateArn: "arn:aws:acm:us-east-1:...",
  hostedZoneId: "Z123456789",
};

new AnalogJS(new Cdk.App(), "myapp-web-prod-stack", config);

Documentation

For detailed documentation on each construct and advanced configurations, see the Wiki.

Static

Guide Description
static-basic.md Deploy a static site or SPA to S3 + CloudFront
static-edge-functions.md Redirects, rewrites, and custom headers via Lambda@Edge
static-full.md Full StaticProps configuration reference

Lambda

Guide Description
lambda-basic.md Deploy a serverless API with Lambda + API Gateway
lambda-containers.md Container images and Bun runtime
lambda-full.md Full LambdaProps configuration reference

Fargate

Guide Description
fargate-basic.md Deploy a containerized service on ECS Fargate
fargate-nixpacks.md Auto-generate Dockerfiles with Nixpacks
fargate-full.md Full FargateProps configuration reference

Serverless (Full-Stack Frameworks)

Guide Description
serverless.md Deploy full-stack meta-frameworks with SSR

Framework Guides

Static Deployment:

Serverless (Lambda + S3 + CloudFront):

Fargate (Containers):

License

Apache-2.0

Packages

 
 
 

Contributors