TypeScript frameworkfor any runtime.

Define one Application Model, then run it on Node.js, Bun, Cloudflare Workers, AWS Lambda, and Electron.Loutre Dev lets you trace the structure and execution from that same model.

npm create loutre@latest my-app
Loutre Dev
http-crudOpen
Graph9 nodes · 9 edges

MULTI-RUNTIME

Develop on the runtime you prefer.

Keep the application model and choose the runtime that fits your environment.Run the same code on Node.js, Bun, Cloudflare Workers, AWS Lambda, or Electron.

Node.js
Bun
app.ts
const application = defineApplication({
  modules: [UsersModule(), HealthModule()],
})

export default application
Loutre
Cloudflare Workers
AWS Lambda
Electron

You shouldn't have to inferthe whole app from files.

Loutre builds Modules, Providers, Executions, and Runtime Capabilities into one canonical Application Model.Its Graph projection keeps ownership, injection, requirements, routes, middleware, and handlers explicit.

From files

src/
  users/
    user.controller.ts
    user.service.ts
    user.repository.ts
  tasks/

Where is this called from?

What does it depend on?

How far did execution get?

With Loutre

executionUsersController

handles: create

entrypointPOST /users
middlewarevalidate.body
handlerUsersController.create

injects

providerUsersService

requires

runtime capabilityhttp.server

The path is explicit.

TYPE INFERENCE

Define types once.

Define the Contract once, and request and response handling stays typed throughout the implementation.

No declare / as / is needed to carry those types.

Contract

const AppContract = http.contract({
  greet: {
    method: 'GET',
    path: '/{name}',
    request: {
      params: {
        name: z.string(),
      },
    },
    responses: {
      ok: {
        status: 200,
        body: z.object({
          message: z.string(),
        }),
      },
    },
  },
})

Implementation

const AppController = http.implementation({
  contract: AppContract,
  factory: () => ({
    greet(ctx) {
      // inferred as string
      const name = ctx.input.params.name

      return ctx.response.ok({
        body: {
          message: `Hello, ${name}!`,
        },
      })
    },
  }),
})

FOR AI AGENTS

One Application Graph.For developers and agents.

Share the same Application Graph with coding agents so structure and dependencies do not have to be inferred from files alone.

Application Graph
executionUsersController
handles
entrypointPOST /users
flows to
handlerUsersController.create
injects
providerUsersService
agent

Agent context

route
POST /users
handler
UsersController.create
depends on
UsersService
source
integrations/http-crud/src/index.ts:54

ARCHITECTURE

One model for the whole application.

Modules, Providers, Executions, and Runtime Capabilities come together in one Application Model shared by Runtime, CLI, DevTools, and OpenAPI.

ApplicationModel / Graph
ModuleOwnership / Visibility
Provider & DIDependencies
ExecutionHTTP / Tasks / MessagePort
Runtime Capabilityhttp.server / queue

One model. Whole picture.

Hello Loutre!

Open the Hello HTTP example in StackBlitz and explore Loutre without setting up a local project.