UNPKG

@thunder-so/thunder

Version:

CDK library for deploying web applications on AWS

632 lines (473 loc) 19.9 kB
# thunder <p> <a href="https://www.npmjs.com/package/@thunder-so/thunder"><img alt="Version" src="https://img.shields.io/npm/v/@thunder-so/thunder.svg" /></a> <a href="https://www.npmjs.com/package/@thunder-so/thunder"><img alt="License" src="https://img.shields.io/npm/l/@thunder-so/thunder.svg" /></a> </p> Build full-stack apps on your own AWS. Thunder is a CDK library and CLI for deploying modern web applications on AWS. One library to rule them all: [Static SPAs](#static), [Lambda Functions](#lambda), [Containers on Fargate](#fargate) and [EC2](#ec2), and [Serverless Full-stack Frameworks](#serverless-frameworks). ## Table of Contents - [Features](#features) - [Supported Frameworks & Patterns](#supported-frameworks--patterns) - [Quick Start](#quick-start) - [Stacks](#stacks) - [Static](#static) - S3 + CloudFront + Route53 - [Lambda](#lambda) - API Gateway + Lambda - [Fargate](#fargate) - ECS Fargate + ALB + CloudFront - [EC2](#ec2) - EC2 + Docker + Elastic IP - [Serverless Frameworks](#serverless-frameworks) - Full-stack meta-frameworks with Lambda + S3 + CloudFront - [Template](#template) - Coolify-style templates - [CLI Commands](#cli-commands) - [Documentation](#documentation) - [License](#license) ## Features - **Constructs:** One-line deployment for `Static`, `Lambda`, `Fargate`, `EC2`, `Serverless`, and framework-specific constructs. - **Thunder CLI (`th`):** Context-aware CLI for initializing, deploying, and managing your infrastructure. - **VPC Link Pattern:** Easily connect your compute resources to a shared VPC. - **High-Performance Serving:** Pre-configured [CloudFront](https://aws.amazon.com/cloudfront/) distributions with OAC, security headers, and edge optimizations. - **Built-in CI/CD:** Optional [AWS CodePipeline](https://aws.amazon.com/codepipeline/) integration with GitHub support. ## Supported Frameworks & Patterns - **Static:** Vite (React, Vue, Svelte, Solid), Next.js (SSG), Astro (SSG), Gatsby. - **Serverless:** Node.js Lambda, Bun, Container-based Lambda. - **Containers:** [ECS Fargate](https://aws.amazon.com/fargate/) with ALB, Docker on [EC2](https://aws.amazon.com/ec2/) with Elastic IP. - **Full-stack SSR:** [Nuxt](https://nuxt.com/), [Astro](https://astro.build/), [TanStack Start](https://tanstack.com/start), [SvelteKit](https://kit.svelte.dev/), [Solid Start](https://start.solidjs.com/), [AnalogJS](https://analogjs.org/). ## Quick Start ### 1. Install ```bash bun add @thunder-so/thunder --development ``` ### 2. Initialize ```bash npx th init ``` ### 3. Configure Create a stack file (e.g., `stack/dev.ts`): ```typescript 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, ); ``` ### 4. Deploy ```bash npx cdk deploy --app "npx tsx stack/dev.ts" --profile default ``` ## Stacks ### Static Deploy static websites to [S3](https://aws.amazon.com/s3/) with [CloudFront](https://aws.amazon.com/cloudfront/) CDN and [Route53](https://aws.amazon.com/route53/) DNS. **Best for:** Static sites, SPAs, JAMstack applications **AWS Resources:** - [S3 Bucket](https://aws.amazon.com/s3/) - Static file hosting - [CloudFront Distribution](https://aws.amazon.com/cloudfront/) - Global CDN with caching - [Route53](https://aws.amazon.com/route53/) - DNS management (optional) - [ACM Certificate](https://aws.amazon.com/certificate-manager/) - SSL/TLS certificates (optional) - [Lambda@Edge](https://aws.amazon.com/lambda/edge/) - Request/response manipulation (optional) **Example:** ```typescript 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](https://aws.amazon.com/api-gateway/) and optional [Lambda Function URL](https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html). **Best for:** Serverless APIs, microservices, event-driven applications **AWS Resources:** - [Lambda Function](https://aws.amazon.com/lambda/) - Compute layer - [API Gateway](https://aws.amazon.com/api-gateway/) - HTTP API with custom domain support - [CloudWatch Logs](https://aws.amazon.com/cloudwatch/) - Logging and monitoring - [Secrets Manager](https://aws.amazon.com/secrets-manager/) - Secure secret injection (optional) **Example:** ```typescript 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](https://aws.amazon.com/fargate/) with Application Load Balancer and [CloudFront](https://aws.amazon.com/cloudfront/). **Best for:** Containerized web applications, microservices, long-running processes **AWS Resources:** - [ECS Cluster](https://aws.amazon.com/ecs/) - Container orchestration - [Fargate Task](https://aws.amazon.com/fargate/) - Serverless containers - [Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/) - Traffic distribution - [ECR Repository](https://aws.amazon.com/ecr/) - Container registry (via CodePipeline) - [CloudWatch Logs](https://aws.amazon.com/cloudwatch/) - Container logging **Example:** ```typescript 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](https://aws.amazon.com/ec2/) instances with Elastic IP for simple, cost-effective hosting. **Best for:** Single-instance applications, development environments, simple Docker deployments **AWS Resources:** - [EC2 Instance](https://aws.amazon.com/ec2/) - Virtual server - [Elastic IP](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) - Static public IP - [VPC](https://aws.amazon.com/vpc/) - Network isolation - [Security Group](https://docs.aws.amazon.com/vpc/latest/userguide/security-groups.html) - Firewall rules - [Route53](https://aws.amazon.com/route53/) - DNS records (optional) **Example:** ```typescript 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:** - [Lambda Function](https://aws.amazon.com/lambda/) - SSR server with container support - [S3 Bucket](https://aws.amazon.com/s3/) - Static assets with OAC - [CloudFront Distribution](https://aws.amazon.com/cloudfront/) - Global CDN with custom domain - [API Gateway](https://aws.amazon.com/api-gateway/) - HTTP API for server functions - [Route53](https://aws.amazon.com/route53/) - DNS management (optional) - [ACM](https://aws.amazon.com/certificate-manager/) - SSL certificates (optional) **Supported Frameworks:** - [TanStack Start](https://tanstack.com/start) - Type-safe full-stack React framework - [Nuxt](https://nuxt.com/) - Vue-based full-stack framework - [Astro](https://astro.build/) - Content-focused web framework with islands architecture - [SvelteKit](https://kit.svelte.dev/) - Svelte-based full-stack framework - [Solid Start](https://start.solidjs.com/) - SolidJS full-stack framework - [AnalogJS](https://analogjs.org/) - Angular-based full-stack framework #### TanStack Start **Example:** ```typescript 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:** ```typescript 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:** ```typescript 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:** ```typescript 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:** ```typescript 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:** ```typescript 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); ``` --- ### Template Deploy [Coolify](https://coolify.io/)-style templates on EC2. Automatically fetches and hydrates Docker Compose templates from the [Coolify templates repository](https://github.com/coollabsio/coolify). **Best for:** Self-hosted applications, databases, dev tools (e.g., n8n, WordPress, databases) **AWS Resources:** Same as [EC2](#ec2) **Example:** ```typescript import { Cdk, Template, type TemplateProps, fetchTemplate, hydrateTemplate, } from "@thunder-so/thunder"; import { InstanceType, InstanceClass, InstanceSize } from "aws-cdk-lib/aws-ec2"; async function main() { // Fetch template from Coolify repository const { parsed: parsedTemplate, port } = await fetchTemplate("n8n"); // Hydrate template with variables const hydrateResult = hydrateTemplate(parsedTemplate, { domain: "n8n.example.com", fallbackPort: port, }); const config: TemplateProps = { env: { account: "123456789012", region: "us-east-1" }, application: "myapp", service: "n8n", environment: "prod", templateSlug: "n8n", instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.MICRO), authorizedKeys: ["ssh-rsa AAAAB3... user@example.com"], hydrateResult, // Optional: Custom domain with SSL domain: "n8n.example.com", hostedZoneId: "Z123456789", acmeEmail: "admin@example.com", }; new Template(new Cdk.App(), "myapp-n8n-prod-stack", config); } main(); ``` **Available Templates:** See the [Coolify templates repository](https://github.com/coollabsio/coolify/tree/v4.x/templates/compose) for available templates. --- ## CLI Commands | Command | Description | | :----------- | :-------------------------------- | | `th init` | Scaffold a new project or service | | `th deploy` | Deploy stacks to AWS | | `th destroy` | Remove resources from AWS | ## Documentation For detailed documentation on each construct and advanced configurations, see the [Wiki](https://github.com/thunder-so/thunder/wiki). ### Static | Guide | Description | | :---------------------------------------------------------- | :------------------------------------------------------ | | [static-basic.md](./docs/static-basic.md) | Deploy a static site or SPA to S3 + CloudFront | | [static-edge-functions.md](./docs/static-edge-functions.md) | Redirects, rewrites, and custom headers via Lambda@Edge | | [static-full.md](./docs/static-full.md) | Full `StaticProps` configuration reference | ### Lambda | Guide | Description | | :-------------------------------------------------- | :------------------------------------------------ | | [lambda-basic.md](./docs/lambda-basic.md) | Deploy a serverless API with Lambda + API Gateway | | [lambda-containers.md](./docs/lambda-containers.md) | Container images and Bun runtime | | [lambda-full.md](./docs/lambda-full.md) | Full `LambdaProps` configuration reference | ### Fargate | Guide | Description | | :------------------------------------------------ | :-------------------------------------------- | | [fargate-basic.md](./docs/fargate-basic.md) | Deploy a containerized service on ECS Fargate | | [fargate-nixpacks.md](./docs/fargate-nixpacks.md) | Auto-generate Dockerfiles with Nixpacks | | [fargate-full.md](./docs/fargate-full.md) | Full `FargateProps` configuration reference | ### Serverless (Full-Stack Frameworks) | Guide | Description | | :------------------------------------ | :----------------------------------------- | | [serverless.md](./docs/serverless.md) | Deploy full-stack meta-frameworks with SSR | ### Framework Guides **Static Deployment:** - [Next.js Static](./docs/frameworks/nextjs-static.md) - [Astro Static](./docs/frameworks/astro-static.md) **Serverless (Lambda + S3 + CloudFront):** - [Nuxt](./docs/frameworks/nuxt-serverless.md) - [Astro SSR](./docs/frameworks/astro-serverless.md) - [TanStack Start](./docs/frameworks/tanstack-start-serverless.md) - [SvelteKit](./docs/frameworks/sveltekit-serverless.md) - [Solid Start](./docs/frameworks/solidstart-serverless.md) - [AnalogJS](./docs/frameworks/analogjs-serverless.md) **Fargate (Containers):** - [Next.js with Dockerfile](./docs/frameworks/nextjs-fargate-dockerfile.md) - [Next.js with Nixpacks](./docs/frameworks/nextjs-fargate-nixpacks.md) - [Astro](./docs/frameworks/astro-fargate.md) - [Nuxt](./docs/frameworks/nuxt-fargate.md) - [TanStack Start](./docs/frameworks/tanstack-start-fargate.md) - [SvelteKit](./docs/frameworks/sveltekit-fargate.md) - [Solid Start](./docs/frameworks/solidstart-fargate.md) - [AnalogJS](./docs/frameworks/analogjs-fargate.md) ## License Apache-2.0