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.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.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