- Developer experience: everyday work needs fast feedback and low boilerplate.
- Performance: prod needs to keep up when traffic spikes and complexity grows.
- Contracts: boundaries need to validate bad data before it reaches domain logic.
.ft source that ships as native Go while allowing incremental migration within your existing TS or Go codebase.
TypeScript
Keeps client-side boilerplate low and makes working with complex data easy.
Go
Compiles fast, ships static binaries, and scales in production.
The analogy
Similar to TypeScript, Forst allows working within your existing codebase and replacing more and more code over time: TypeScript added types on top of JavaScript while keeping the same runtime. Forst does the same on both sides of your stack:- Go: Ship native binaries with
go buildand typed boundaries layered on top. See Go interop. - Node: Stay type-aligned with the frontend and migrate route by route without a big bang rewrite. See Node interop.
Feature comparison
Compare Forst to TypeScript and Go.Compatibility
How each stack talks to other languages and adopts code incrementally.Language
How each language models data, errors, and concurrency.Infrastructure
How you ship, debug, and adopt each stack day to day.Go import loading, Node interop, Providers, and several invoke paths are experimental. See the roadmap for current status.
What you get
Structural typing on the server
Typed records with field access, signatures, and
is narrowing. You define one schema layer for the server.Validation on the type
Constraints on fields. The compiler checks known values at compile time and emits runtime checks at the boundary.
Generate client types
forst generate emits .d.ts from the same .ft definitions the server uses.Production Go output
Readable Go output. Ship with
go build, existing modules, tests, and CI.Explicit failures
ensure, nominal error types, and Result. Failures are values you handle in control flow.Gradual adoption
Mix
.ft with .go. Migrate route by route with forst dev or @forst/sidecar.Design priorities
Structural typing
Shape matters more than inheritance.
Boundary validation
Types and runtime checks run before your logic.
Predictable behavior
Require explicit annotations where inference would lie.
Fast tooling
Inference applies only in clear cases.
Go as runtime
Import Go packages. Deploy with
go build.APIs for consumption
Export types when full stack teams need shared shapes.
What Forst omits
Surprising errors
No
try / catch / throw. Failures are values you handle or explicitly ignore. ensure signals intent.Class hierarchies
Inheritance trees obscure which fields an API actually has.
Macros and metaprogramming
Control flow changes use ordinary keywords you can read top to bottom.
Runtime reflection
Wiring and validation happen at compile time instead of through introspection.
Dependent types
Types cannot depend on runtime values.
Implicit coercions
Conversions stay visible because backend data integrity matters.
Panics may appear in generated Go or third-party libraries. Forst itself favors
Result and Go’s error returns.Read more
Language overview
How the language feels day to day.
Roadmap
What exists, what’s experimental, what’s planned.
Quickstart
Install and run your first handler.
Full philosophy (GitHub)
Long-form design doc in the repository.