Structured Apps of any size
Organize code into layers with Actions, Services, Repos, and Facades. Scale with modules when needed. Great for both small and large apps.
Vla is also a smooth, pudding-like Dutch dessert that goes with everything.
Structured Apps of any size
Organize code into layers with Actions, Services, Repos, and Facades. Scale with modules when needed. Great for both small and large apps.
Framework Agnostic
Works with Next.js, SvelteKit, Tanstack, Express, and any other server-side framework in TypeScript or JavaScript.
Testing Friendly
Clean Dependency Injection without decorators or reflection. Write code that’s easy to test without module mocks.
No Extra Tooling
Install and you’re ready. No extra tooling or plugins to configure. No incompatibility when upgrading your framework.
import { Vla } from 'vla'
// Create an action as your entry pointclass ShowUser extends Vla.Action { repo = this.inject(UserRepo)
async handle(userId: string) { return this.repo.findById(userId) }}
// Define a repository for data accessclass UserRepo extends Vla.Repo { db = this.inject(Database)
// ⭐ built-in memoization findById = this.memo((id: string) => { return this.db.users.find({ id }) })}
// Use Services for business rules and resources for infrastructureclass UserService extends Vla.Service { // reusable business rules}class Database extends Vla.Resource { static readonly unwrap "db" db = this.devStable("db", () => new FavoriteOrm()) // ⭐ devStable() prevents creating new clients in hot-reload dev mode}
// Grow your app with Modules and Facadesconst Billing = Vla.createModule("Billing")class BillingFacade extends Billing.Facade { // Facades are public interfaces for cross-module dependencies}
// Initialize Vla's Kernelconst kernel = new Vla.Kernel()Vla.setGlobalInvokeKernel(kernel)
// Invoke from your frameworkconst user = await ShowUser.invoke(userId)Ready to add some smooth deliciousness to your backend? Check out the Getting Started guide to begin using Vla in your project.