A monorepo containing lightweight TypeScript libraries for algebraic effects and related utilities.
A lightweight 3kB Effect-TS alternative library based on Algebraic Effects.
Features:
- Lightweight: Only 3kB minified and gzipped
- Type Safe: Full TypeScript support with excellent type inference
- Algebraic Effects: Based on proven algebraic effects theory
- Async Support: Seamless integration with Promises and async/await
- Error Handling: Powerful error handling with type safety
- Context Management: Dependency injection made simple
- Task Management: Concurrent task execution with control
Quick Start:
import * as Koka from 'koka'
import * as Err from 'koka/err'
import * as Ctx from 'koka/ctx'
// Define your effects
class UserNotFound extends Err.Err('UserNotFound')<string> {}
class AuthToken extends Ctx.Ctx('AuthToken')<string> {}
// Write effectful code
function* getUser(id: string) {
const token = yield* Ctx.get(AuthToken)
if (!token) {
yield* Err.throw(new UserNotFound('No auth token'))
}
return { id, name: 'John Doe' }
}
// Handle effects
const program = Koka.try(getUser('123')).handle({
UserNotFound: (error) => ({ error }),
AuthToken: 'secret-token',
})
const result = Koka.run(program)Documentation: 📖 Full Documentation
Accessors library for immutable data manipulation.
State management library with algebraic effects.
Our documentation follows the Diátaxis framework for comprehensive, user-friendly guides:
- Getting Started - Your first steps with Koka
- Core Concepts - Understanding algebraic effects
- Error Handling - Managing errors with type safety
- Migration Guide - Step-by-step migration
- Effect-TS Comparison - Detailed comparison
- Context Management - Dependency injection
- Async Operations - Working with Promises
- Task Management - Concurrent operations
- API Reference - Complete API documentation
- 3kB minified and gzipped (vs ~50kB for Effect-TS)
- Minimal runtime overhead
- Tree-shakeable for optimal bundle size
- Full TypeScript support
- Excellent type inference
- Compile-time effect checking
- Familiar generator syntax (
function*,yield*) - Simple API design
- Gentle learning curve
- Comprehensive error handling
- Async/await integration
- Concurrent task management
- Dependency injection
| Aspect | Koka | Effect-TS |
|---|---|---|
| Bundle Size | ~3kB | ~50kB |
| API Style | Object-oriented | Functional |
| Learning Curve | Gentle | Steep |
| Type Safety | Excellent | Excellent |
| Performance | Minimal overhead | Higher overhead |
| Ecosystem | Lightweight | Rich ecosystem |
# Install core package
npm install koka
# Install additional packages
npm install @koka/accessor @koka/storeAll code examples in our documentation use the import * as XXX from 'xxx' style for consistency:
// ✅ Correct import style (as used in tests)
import * as Koka from 'koka'
import * as Err from 'koka/err'
import * as Ctx from 'koka/ctx'
import * as Async from 'koka/async'
import * as Task from 'koka/task'
import * as Result from 'koka/result'
import * as Opt from 'koka/opt'
import * as Gen from 'koka/gen'
// ❌ Not used in this documentation
import { try, run } from 'koka'
import { Err, Ctx } from 'koka'import * as Koka from 'koka'
import * as Err from 'koka/err'
class ValidationError extends Err.Err('ValidationError')<{ field: string; message: string }> {}
function* validateUser(user: any) {
if (!user.name) {
yield* Err.throw(
new ValidationError({
field: 'name',
message: 'Name is required',
}),
)
}
return user
}
const program = Koka.try(validateUser({})).handle({
ValidationError: (error) => ({ error, status: 'error' }),
})
const result = Koka.run(program)import * as Koka from 'koka'
import * as Ctx from 'koka/ctx'
import * as Async from 'koka/async'
class Database extends Ctx.Ctx('Database')<{
query: (sql: string) => Promise<any>
}> {}
function* getUser(id: string) {
const db = yield* Ctx.get(Database)
const user = yield* Async.await(db.query(`SELECT * FROM users WHERE id = '${id}'`))
return user
}
const program = Koka.try(getUser('123')).handle({
Database: {
query: async (sql) => ({ id: '123', name: 'John Doe' }),
},
})
const result = await Koka.run(program)import * as Koka from 'koka'
import * as Task from 'koka/task'
function* getUserProfile(userId: string) {
const result = yield* Task.object({
user: () => fetchUser(userId),
posts: () => fetchPosts(userId),
comments: () => fetchComments(userId),
})
return result
}
const profile = await Koka.run(getUserProfile('123'))- Node.js >= 22.18
- TypeScript >= 5.0
Koka requires:
- ES2015+ (for generators)
- Promise support
- Symbol support
For older browsers, consider using a polyfill or transpiler.
# Install dependencies
pnpm install
# Run tests
pnpm test
# Run tests with coverage
pnpm test:coverage
# Build all packages
pnpm build
# Sync repository structure
pnpm sync-repoWe welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
MIT License - see LICENSE for details.
- Effect-TS - Comprehensive algebraic effects library
- Algebraic Effects Research - Theory behind algebraic effects
Made with ❤️ by the Koka team