Skip to content

Hero64/lafken

Lafken

A TypeScript framework for building serverless applications on AWS using decorators.

Lafken simplifies AWS infrastructure by letting you define resources with decorators in your TypeScript code. Focus on your application logic while Lafken automatically generates and manages all the infrastructure using Terraform.

Lafken leverages cdk-terrain to transform application code into Terraform-based infrastructure.

If you find Lafken useful, please consider supporting the cdk-terrain project. Your support helps us grow the ecosystem and continue building better tools together.

✨ Key Features

  • Decorator-Based: Define infrastructure with familiar TypeScript decorators
  • Type-Safe: Full TypeScript support with autocomplete for resources
  • Zero Configuration: Start building immediately with sensible defaults
  • Modular: Organize resources into logical modules
  • Extensible: Create custom resolvers for additional AWS services
  • Infrastructure as Code: Infrastructure is version-controlled TypeScript code

πŸš€ Getting Started

Installation

Create a new Lafken project:

npm create lafken@latest

Or install in an existing TypeScript project:

npm install @lafken/main @lafken/api @lafken/common

System Requirements

  • Node.js >= 20.19
  • pnpm >= 10.20.0
  • TypeScript >= 5.0

πŸ“š Core Concepts

Lafken works through three key components:

  1. Decorators: Mark your classes and methods to define infrastructure (@Api, @Get, @Queue, etc.)
  2. Modules: Group related resources together with shared configuration
  3. App: Register modules and resolvers to generate your infrastructure

Here's the flow:

TypeScript Code (with decorators)
    ↓
Module (groups resources)
    ↓
App + Resolvers (processes decorators)
    ↓
Terraform Configuration (generated automatically)

πŸ’‘ 5-Minute Example

Here's a complete serverless API:

1. Define Your Resource

import { Api, Get, ApiRequest, PathParam  } from '@lafken/api/main';

@ApiRequest()
export class HelloRequestEvent {
  @PathParam()
  name: number;
}


@Api({
  path: '/hello'
})
export class HelloApi {
  @Get({
    path: '/{name}'
  })
  greet(@Event(HelloRequestEvent) event: HelloRequestEvent) {
    return {
      message: `Hello, ${event.name}!`
    };
  }
}

2. Create a Module

import { createModule } from '@lafken/main';

export const helloModule = createModule({
  name: 'hello-module',
  resources: [HelloApi],
});

3. Create Your App

import { createApp } from '@lafken/main';
import { ApiResolver } from '@lafken/api/resolver';

createApp({
  name: 'hello-app',
  resolvers: [new ApiResolver()],
  modules: [helloModule],
});

That's it! Lafken generates all the AWS infrastructure:

  • API Gateway REST API
  • Lambda function
  • IAM roles with least-privilege permissions
  • Terraform configuration

πŸ”§ Advanced Features

Environment Variables

Define environment variables for your Lambda functions with support for static and dynamic values:

@Api({ path: '/users' })
export class UserApi {
  @Get({
    path: '/{id}',
    lambda: {
      env: ({ getResourceValue }) => ({
        // Static value
        APP_NAME: 'my-app',
        
        // Environment variable
        DEBUG: process.env.DEBUG || 'false',
        
        // Dynamic reference to another resource
        TABLE_NAME: getResourceValue('dynamo::users', 'name'),
        
        // AWS Systems Manager Parameter Store
        API_KEY: 'SSM::STRING::/my-app/api-key'
      }),
    }
  })
  getUser() { /* ... */ }
}

Type-Safe Resource References

Enable TypeScript autocomplete for your infrastructure:

Create lafken-types.d.ts in your project root:

declare module '@lafken/common' {

  // Register application modules
  interface ModulesAvailable {
    // Module name
    greeting: {
      // STATE MACHINE resources within the module
      StateMachine: {
        // Resource name mapped to a boolean flag
        GreetingStepFunction: true;
      };
      // QUEUE resources within the module
      Queue: {
        'greeting-standard-queue': true;
      };
    };
  }

  // bucket
  interface BucketAvailable {
    'lafken-example-documents': true;
  }
  // api
  interface ApiRestAvailable {
    UserApi: true;
  }

  interface DynamoTableAvailable {
    users: true;
  }
}

export {};

Now you get full autocomplete:

getResourceValue('dynamo::users', 'arn')  // βœ“ TypeScript knows this is valid
getResourceValue('dynamo::invalid', 'arn') // βœ— TypeScript error

Creating Custom Resolvers

Extend Lafken with your own AWS services:

import { ResolverType } from '@lafken/resolver';

export class MyServiceResolver implements ResolverType {
  async beforeCreate(scope) { /* Shared resources */ }
  async create(module, resource) { /* Process resource */ }
  async afterCreate(scope) { /* Configure integrations */ }
}

πŸ“– Complete Package Documentation

Lafken is organized into focused packages. Here's what each does:

Package Purpose
@lafken/main Core engine - create apps and modules
@lafken/api REST APIs with API Gateway
@lafken/queue SQS queues and message processing
@lafken/event EventBridge event buses
@lafken/schedule Scheduled Lambda functions
@lafken/state-machine Step Functions workflows
@lafken/bucket S3 bucket management
@lafken/dynamo DynamoDB tables
@lafken/auth Cognito authentication
@lafken/resolver Base utilities for creating resolvers
@lafken/common Decorators and type utilities

View full documentation for each package:

🀝 Contributing

We welcome contributions! Here are some ways to help:

πŸ›‘οΈ Security

Found a security vulnerability? Please report it responsibly via SECURITY.md. Do not open public issues for security vulnerabilities.

πŸ“œ License

MIT License - see LICENSE file for details.

❓ Need Help?


Happy building with Lafken! πŸš€

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors