What if TypeScript
was purely functional?

typelang is a strict functional subset of TypeScript with algebraic effects, enforced purity, and zero runtime errors. Build reliable software with effect tracking and exhaustive pattern matching.

Zero Dependencies 100% TypeScript Effect Tracking Subset Enforced
// Counter with Console + State
const tick = () =>
  seq()
    .let(() => State.get<{count: number}>())
    .let((s) => ({count: s.count + 1}))
    .do((next) => Console.op.log(`Count: ${next.count}`))
    .do((next) => State.put(next))
    .return((next) => next.count);

Click "Run" to see the handlers execute live.

Traditional TypeScript

// Mutation everywhere
let count = 0;
function increment() {
  count++;  // Side effect!
  console.log(count);  // Another side effect!
  return count;
}
  • ❌ Hidden mutation makes testing hard
  • ❌ Side effects not tracked in types
  • ❌ No guarantee of execution order
  • ❌ Cannot safely parallelize

typelang

// Pure transformation
const increment = () =>
  seq()
    .let(() => State.get<{count: number}>())
    .let((state) => ({count: state.count + 1}))
    .do((next) => Console.op.log(`${next.count}`))
    .do((next) => State.put(next))
    .return((next) => next.count);
  • ✅ All effects tracked in type signature
  • ✅ Pure functions = easy testing
  • ✅ Explicit sequencing with seq()
  • ✅ Handler swapping for different contexts

Why typelang?

Three core principles for reliable software

🔍

Effect Tracking

All side effects visible in function signatures. No surprises.

  • Type system tracks Console, State, Exception, Async
  • Compiler errors if effects not handled
  • Documentation via types
  • Refactoring confidence
🛡️

Zero Runtime Errors

Pattern matching and Result types eliminate exceptions.

  • Exhaustive case analysis
  • Errors as typed values
  • No try/catch needed
  • Test error paths easily
🧬

Enforced Purity

Subset linter prevents mutations, loops, and if/else.

  • No classes or inheritance
  • Immutable data structures
  • Expression-oriented code
  • CI-enforced constraints

Start Learning

Choose your path based on your experience level

🌱

New to Functional Programming

Start with the basics: seq(), match(), pipe(), and simple effects.

~15 min

Experienced FP Developer

Jump to algebraic effects, handler composition, and advanced patterns.

~10 min
🎮

Interactive Playground

Experiment with live code, try examples, and see instant results.

Explore at your pace

Ready to build with effects?

Explore interactive demos, try the playground, or dive into the comprehensive guide.

Explore Demos