@forthix/forthic
v0.16.0
Published
Stack-based, concatenative language for composable transformations - TypeScript/JavaScript runtime
Maintainers
Readme
Forthic TypeScript Runtime
A TypeScript/JavaScript runtime for Forthic - the stack-based, concatenative language for composable transformations.
Use Forthic to wrap your TypeScript/JavaScript code within composable words, leveraging categorical principles for clean, powerful abstractions.
Learn at forthix.com | Forthic Docs | Getting Started | Examples | API Docs
What is Forthic?
Forthic enables categorical coding - a way to solve problems by viewing them in terms of trasnformation rather than copmutation. This TypeScript runtime lets you:
- Wrap existing code with simple decorators
- Compose transformations cleanly using stack-based operations
- Build powerful abstractions from simple primitives
Learn more about Categorical Coding →
See the Forthic repository for technical documentation and API references.
Quick Example
Create a Module
import { DecoratedModule, Word } from '@forthix/forthic';
export class AnalyticsModule extends DecoratedModule {
constructor() {
super("analytics");
}
@Word("( numbers:number[] -- avg:number )", "Calculate average")
async AVERAGE(numbers: number[]) {
return numbers.reduce((a, b) => a + b, 0) / numbers.length;
}
@Word("( numbers:number[] stdDevs:number -- filtered:number[] )", "Filter outliers")
async FILTER_OUTLIERS(numbers: number[], stdDevs: number) {
// Your existing logic here
return filteredNumbers;
}
}Use It
import { Interpreter } from '@forthix/forthic';
import { AnalyticsModule } from './analytics-module';
const interp = new Interpreter();
interp.register_module(new AnalyticsModule());
await interp.run(`
["analytics"] USE-MODULES
[1 2 3 100 4 5] 2 FILTER-OUTLIERS AVERAGE
`);
const result = interp.stack_pop(); // Clean average without outliersInstallation
npm
npm install @forthix/forthicyarn
yarn add @forthix/forthicRequirement: a global Temporal
Forthic's date and time values are built on the TC39 Temporal API. The runtime references a global Temporal object and does not bundle a polyfill, so the host is responsible for providing one. Any Forthic program that uses dates/times (TODAY, NOW, date literals like 2020-06-05, the datetime module, or wire serialization of temporal values) will throw Temporal is not defined if no global Temporal is available.
Native Temporal is not yet shipped unflagged in Node.js, Chrome, or Safari, so most consumers need a polyfill. Install temporal-polyfill and import it once at your application's entry point, before running any Forthic:
npm install temporal-polyfillimport "temporal-polyfill/global"; // installs globalThis.Temporal
import { Interpreter } from "@forthix/forthic";temporal-polyfill is declared as an optional peer dependency: skip it only if your runtime already provides a native global Temporal, or if your programs never touch dates/times. For TypeScript type-checking of Temporal types, also add temporal-spec as a dev dependency.
Getting Started
Node.js Usage
import { Interpreter } from '@forthix/forthic';
const interp = new Interpreter();
// Execute Forthic code
await interp.run(`
[1 2 3 4 5] "2 *" MAP # Double each element
`);
const result = interp.stack_pop(); // [2, 4, 6, 8, 10]Browser Usage
<script type="module">
import { Interpreter } from 'https://unpkg.com/@forthix/forthic';
const interp = new Interpreter();
await interp.run('[1 2 3] "2 *" MAP');
console.log(interp.stack_pop()); // [2, 4, 6]
</script>Creating Your First Module
import { DecoratedModule, Word } from '@forthix/forthic';
export class MyModule extends DecoratedModule {
constructor() {
super("mymodule");
}
@Word("( data:any[] -- result:any )", "Process data your way")
async PROCESS(data: any[]) {
// Wrap your existing code
return myExistingFunction(data);
}
}
// Register and use
const interp = new Interpreter();
interp.register_module(new MyModule());
await interp.run(`
["mymodule"] USE-MODULES
SOME-DATA PROCESS
`);See examples/README.md for detailed tutorials and examples.
Features
Standard Library
The TypeScript runtime includes comprehensive standard modules:
- array - MAP, SELECT, SORT, GROUP-BY, ZIP, REDUCE, FLATTEN (30+ operations)
- record - REC@, <REC, MERGE, KEYS, VALUES, INVERT-KEYS
- string - SPLIT, JOIN, UPPERCASE, LOWERCASE, TRIM, REPLACE
- math - +, -, *, /, ROUND, ABS, MIN, MAX, AVERAGE
- datetime - >DATE, >DATETIME, ADD-DAYS, FORMAT, DIFF-DAYS (Temporal API)
- json - >JSON, JSON>, JSON-PRETTIFY
- boolean - ==, <, >, AND, OR, NOT, IN
See docs/modules/ for complete reference.
Easy Module Creation
The @Word decorator makes wrapping code trivial:
@Word("( input:type -- output:type )", "Description", "MY-WORD")
async MY_WORD(input: any) {
return yourLogic(input);
}TypeScript & JavaScript Support
- Full TypeScript type definitions
- Works with ES modules and CommonJS
- Browser and Node.js compatible
- Supports async/await
Package Exports
forthic-ts provides multiple import paths for different use cases:
// Main package - Core interpreter and standard library (works everywhere)
import { Interpreter, DecoratedModule, Word } from '@forthix/forthic';
// WebSocket support - Browser-compatible multi-runtime execution
import { ActionCableClient, WebSocketRemoteModule } from '@forthix/forthic/websocket';
// JSON-RPC support - Node.js-only multi-runtime execution
import { JsonRpcClient, RemoteModule, startJsonRpcServer } from '@forthix/forthic/jsonrpc';Environment Compatibility:
- Main package (
@forthix/forthic): Works in both Node.js and browsers - WebSocket (
@forthix/forthic/websocket): Works in both Node.js and browsers - JSON-RPC (
@forthix/forthic/jsonrpc): Node.js only (useshttpand globalfetch)
Documentation
Learning Resources
- forthix.com - Learn about Forthic and Categorical Coding
- Category Theory for Coders - Understand the foundations
This Runtime
- Getting Started - TypeScript-specific setup
- Module API Reference - Standard library documentation
- Examples - Working code samples
Core Forthic Concepts
- Main Forthic Docs - Philosophy, language guide
- Why Forthic? - Motivation and core principles
- Category Theory - Mathematical foundations
- Building Modules - Module creation patterns
Examples
See examples in the examples directory.
Building
# Install dependencies
npm install
# Build both CJS and ESM
npm run build
# Run tests
npm test
# Generate documentation
npm run docs:buildMulti-Runtime Execution
Call code from other language runtimes seamlessly - use Python's pandas from TypeScript, or TypeScript's fs module from Ruby.
Quick Example
import { Interpreter } from '@forthix/forthic';
import { JsonRpcClient, RemoteModule } from '@forthix/forthic/jsonrpc';
const interp = new Interpreter();
// Connect to Python runtime
const client = new JsonRpcClient('localhost:8765');
const pandas = new RemoteModule('pandas', client, 'python');
await pandas.initialize();
interp.register_module(pandas);
// Now use Python pandas from TypeScript!
await interp.run(`["pandas"] USE-MODULES [records] DF-FROM-RECORDS`);Approaches
- JSON-RPC - Node.js ↔ Python ↔ Ruby (server-to-server, no native dependencies)
- WebSocket - Browser ↔ Rails (ActionCable, client-server)
Learn More
📖 Complete Multi-Runtime Documentation
- Overview - When and how to use multi-runtime
- JSON-RPC Setup - Server and client configuration
- WebSocket Setup - Browser-compatible communication
- Configuration - YAML config and connection management
- Examples - Working code samples (05-jsonrpc-server.ts, 06-jsonrpc-client.ts)
Runtime Status: ✅ TypeScript, Python, Ruby | 🚧 Rust | 📋 Java, .NET
Contributing
We welcome contributions! See CONTRIBUTING.md for:
- Development setup
- TypeScript coding standards
- Testing guidelines
- PR process
Also see the main Forthic contributing guide for philosophy and community guidelines.
Community
- Main Repository: forthix/forthic
- Issues: Report issues
- Discussions: GitHub Discussions
- Examples: Real-world applications
License
BSD-2-Clause License - Copyright 2024 LinkedIn Corporation. Copyright 2025 Forthix LLC.
Related
- Forthic (main repo) - Core documentation and concepts
Forthic: Wrap. Compose. Abstract.
