Skip to content

🌿 A statically-typed, functional language with Python aesthetics that compiles to single binaries

License

Notifications You must be signed in to change notification settings

niklas-heer/fern

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

325 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌿 Fern

A statically-typed, functional language with Python aesthetics that compiles to single binaries.

Status: 🚧 In active development - Gate D complete, 484 tests passing, release packaging/benchmark publishing in CI, and a new Justfile task runner

What is Fern?

Fern is a programming language designed to make both fast CLI tools (<1 MB) and full-stack applications (2-4 MB) with the same elegant syntax. No runtime dependencies, no crashes, predictable behavior.

# Clean, readable syntax with explicit error handling
let content = read_file("config.txt")?
let config = parse_config(content)?
let validated = validate(config)?
Ok(process(validated))

Design Philosophy

Fern should spark joy - for those familiar with functional programming, writing Fern should feel delightful, not tedious.

One obvious way - There should be one clear, idiomatic way to accomplish any task. No agonizing over which of five approaches to use.

No surprises - The language actively prevents the bugs that waste your afternoon. If it compiles, it probably works.

Jetpack included - Everything you need is built-in: actors, databases, HTTP, CLI tools, TUI. Like Bun, but compiled.

Core Principles

Principle How Fern Delivers
Readable Python-like indentation, no braces, clear keywords
Functional Immutable by default, pure functions, pattern matching
Safe No null, no exceptions, no panics - only Result/Option types
Predictable Explicit error handling, no hidden control flow, exhaustive matching
Fast Compiles to native code, ~35x faster than Python
Portable Single binary, no runtime dependencies

What We Prevent

βœ— NullPointerException     β†’ Option type, exhaustive matching
βœ— Unhandled exceptions     β†’ Result type, must handle errors
βœ— Race conditions          β†’ Actors with isolated heaps, no shared state
βœ— "It works on my machine" β†’ Single binary, all dependencies included
βœ— Silent failures          β†’ Compiler enforces error handling
βœ— Action at a distance     β†’ Immutability prevents spooky mutation

Key Features

  • Static types with inference - safety without verbosity
  • Pattern matching - exhaustiveness checking catches bugs
  • Garbage collected runtime - Boehm-backed runtime plus Perceus baseline ownership primitives
  • Language tooling - LSP with diagnostics, hover, definition, completion, rename, and code actions
  • Stable stdlib API surface - fs, http, json, sql, actors, and File alias compatibility
  • Helpful diagnostics - snippets, notes, and fix hints in CLI workflows
  • Reproducible quality gates - just check (or make check), fuzz smoke, perf budgets, release policy checks

Current Status

Fern is implemented with strict TDD. See DESIGN.md for language details and ROADMAP.md for gate-by-gate status.

Execution gates:

  • βœ… Gate A (DX + language feel) passed
  • βœ… Gate B (reliability + regression resistance) passed
  • βœ… Gate C (stdlib/runtime surface quality) passed
  • βœ… Gate D (ecosystem/adoption hardening) passed

Recent outcomes:

  • βœ… 484/484 tests passing in local make test
  • βœ… Cross-platform CI (Ubuntu + macOS) with build/test/style/perf/fuzz/example checks
  • βœ… Release packaging bundles (fern + libfern_runtime.a + policy/docs artifacts)
  • βœ… Conventional-commit-driven semver + release notes via release-please
  • βœ… Published reproducible benchmark + case-study report in docs/reports/benchmark-case-studies-2026-02-06.md
  • βœ… LSP support beyond MVP (completion, rename, code actions, better source positions)

Active focus:

  • 🚧 Post-Gate D stabilization and milestone polish (see ROADMAP.md)

Documentation

Inspiration

Fern takes inspiration from the best features of:

  • Gleam - Type system, simplicity
  • Elixir - Pattern matching, actors, pragmatic design
  • Rust - ? operator, Result types
  • Zig - Comptime, defer, minimalism
  • Python - Readability, aesthetics
  • Go - Single binary deployment

Philosophy in Action

Replace your infrastructure:

# No Redis, no RabbitMQ, no separate database
fn main() -> Result[(), Error]:
    let db = sql.open("app.db")?           # Embedded database
    let cache = spawn(cache_actor)          # In-memory cache (actor)
    let queue = spawn(job_queue)            # Job queue (actor)

    http.serve(8080, handler(db, cache, queue))

# One 3.5MB binary, no external dependencies

CLI tools stay tiny:

# Fast, small, no runtime
fn main() -> Result[(), Error]:
    let data = read_file("data.csv")?
    let processed = process(data)?
    write_file("output.csv", processed)?
    Ok(())

# 600KB binary, <5ms startup

Building

Dependencies (for building the compiler):

# macOS
brew install bdw-gc

# Ubuntu/Debian
apt install libgc-dev

# Fedora
dnf install gc-devel

Note: QBE is embedded in the compiler - no external qbe binary needed. Boehm GC is statically linked into compiled programs. The fern binary and compiled programs are fully standalone - no runtime dependencies, just like Go.

Preferred task runner (Justfile):

just debug
just test
just check
just release-package
just benchmark-report

Justfile is the primary developer entrypoint and delegates to the existing Makefile backend.

Direct Make targets (still supported):

make           # Debug build (default)
make debug     # Debug build with symbols
make release   # Optimized release build
make test      # Run test suite
make check     # Build + tests + examples + strict style checks
make style     # Check FERN_STYLE compliance only
make release-package   # Build + package release bundle into dist/
make benchmark-report  # Publish reproducible benchmark + case-study report

Release Automation

Fern uses release-please with conventional commits to drive release PRs, semver bumps, and changelog notes automatically. The initial release baseline is pinned to 0.1.0 (not 1.0.0).

  • fix: commits trigger patch bumps
  • feat: commits trigger minor bumps
  • feat!: or BREAKING CHANGE: triggers minor bumps while <1.0.0 (and major bumps once >=1.0.0)
  • Release notes/changelog entries are generated from conventional-commit history

The workflow in .github/workflows/release-please.yml requires RELEASE_PLEASE_TOKEN to be set in repo secrets to open/update release PRs.

FAQ

Why "Fern"?

Ferns are ancient, resilient plants that have survived for over 350 million years. Like the plant, Fern the language is designed to be:

  • Resilient - No crashes, no nulls, explicit error handling
  • Elegant - Simple fronds (syntax) that unfold into complex patterns
  • Evergreen - Clean fundamentals that age well

Plus, it's short, memorable, and wasn't taken.

What's with the 🌿 emoji?

The fern emoji (🌿) is Fern's visual identity. You can even use it as a file extension:

# Both work!
fern build hello.fn
fern build hello.🌿

Why? Because we can, and it makes your file explorer more interesting.

Is Fern production-ready?

Not yet. Core compiler/runtime/tooling paths are heavily tested and Gate D is complete, but Fern is still pre-1.0 and evolving. See ROADMAP.md and docs/COMPATIBILITY_POLICY.md for current guarantees and planned work.

License

MIT License - see LICENSE for details.

What this means: You can use Fern for anything (personal, commercial, proprietary) without restrictions. We want Fern to be as widely useful as possible.

Contributing

We're actively implementing the compiler using AI-assisted test-driven development. See CLAUDE.md for development workflow and guidelines.

# Build and test
make test

# Check style compliance
make style

# See current progress
cat ROADMAP.md

About

🌿 A statically-typed, functional language with Python aesthetics that compiles to single binaries

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •