Scheme is the quiet survivor of the Lisp family. It never won a popularity contest, yet it runs package managers, music engravers, debuggers, language implementations and a growing number of network services. The reason is structural: a hygienic macro system, proper tail calls, first-class continuations and a language small enough that one person can understand the whole implementation.

In 2026 three implementations matter for production work: Racket (v9.3, 5,208 GitHub stars), Chez Scheme (v10.4.1, 7,348 stars) and GNU Guile (3.0.x). They are all Scheme, they all compile, and they solve different problems. Racket gives you a platform with an IDE, a package manager and a language-authoring toolkit. Chez gives you a legendary native compiler that other languages borrow. Guile gives you a small embeddable interpreter with the GNU ecosystem behind it.

TL;DR — Quick Verdict

Pick Racket if you want a complete platform: DrRacket IDE, raco package manager, a batteries-included standard library, and the ability to design your own language as easily as writing a module. Pick Chez Scheme if raw compile speed and a tiny runtime matter — it is the fastest of the three, ships as a single native compiler, and is the backend other serious projects (including Racket’s own core and the Idris 2 compiler) chose for the same reason. Pick GNU Guile if you are embedding an interpreter into a C application, writing scripts that extend existing GNU software, or living inside the Guix package manager ecosystem. Platform, speed, embedding — in that order.

Implementation Comparison Table

GitHub and release data collected 13 September 2026.

ImplementationStarsLatest releaseCompilation modelPackage ecosystemIDE / toolingOfficial container
Racket5,208v9.3 (2026-08-13)Racket CS (built on Chez) + bytecode variantraco pkg catalog, 2,000+ packagesDrRacket, raco CLI, LSPracket/racket:9.3
Chez Scheme7,348v10.4.1 (2026-05-12)Native code compilerSmall; akku plus community librariesChez REPL, Emacs modeNone official
GNU GuileNot on GitHub (GNU Savannah)3.0.xBytecode VM with native-code JITSRFI + GNU ecosystem modulesREPL, Emacs GeiserNone official
CHICKEN SchemeNot on GitHub (call-cc.org)6.0.0Scheme → C → nativeLarge eggs repositorycsi REPL, cscNone official

Star counts systematically understate Guile and CHICKEN: both predate GitHub and are hosted on their own forges (GNU Savannah and call-cc.org), and Guile’s largest deployment — the Guix package manager ecosystem — is not measured in stars at all.

Decision Matrix: Match the Implementation to the Job

Use caseRecommended implementationWhy
Scripting a web service or APIRacketracket/web-server plus raco packaging; container image ready to use
Extending a C or C++ applicationGNU GuilePurpose-built libguile embedding API; the same design used by GDB and LilyPond
Maximum execution speedChez SchemeNative compiler with decades of optimisation; architecture other projects adopt wholesale
Writing a new language or DSLRacket#lang modules make language definition a first-class, documented workflow
Small runtime footprint / writing to CCHICKEN SchemeCompiles to portable C; tiny runtime, easy to vendor
Scripting inside a GNU/Guix environmentGNU GuileNative Guile modules are the extension language for that entire ecosystem
Teaching or research on macrosRacketBest documentation and tooling for macro development
Embedding Scheme in a game engine or CLIChez SchemeSmall binary, drops into a C host with minimal glue

Racket — A Platform, Not Just an Interpreter

Racket is what happens when a Scheme implementation grows a standard library, an IDE, a package manager, a documentation tool and a language-creation framework. Since Racket 8.0 the main distribution (Racket CS) has been built on top of Chez Scheme, which gives it native-code performance while keeping the Racket language and library surface.

Racket IDE and editor integration from the official site

Install it natively:

1
2
3
4
5
6
7
8
# Debian / Ubuntu
sudo apt install racket

# macOS
brew install --cask racket

# Install a package from the catalog
raco pkg install web-server

Deploy a service with the official image:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
services:
  racket-app:
    image: racket/racket:9.3
    container_name: racket-service
    working_dir: /app
    volumes:
      - ./:/app:ro
    command: ["racket", "/app/server.rkt"]
    ports:
      - "8080:8080"
    restart: unless-stopped
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#lang racket
(require web-server/servlet
         web-server/servlet-env)

(define (start request)
  (define path (url->string (request-uri request)))
  (response/xexpr
   `(html (head (title "Scheme Service"))
          (body (h1 "Serving ") (p ,path)))))

(serve/servlet start
               #:port 8080
               #:servlet-path "/"
               #:launch-browser? #f)

Racket macro system illustration from the official site

Where it wins: nothing else in the Scheme world gives you a package manager, an IDE, a documentation generator, a test framework and a GUI toolkit in one install. Where it costs you: the platform is large — a Racket container is measured in hundreds of megabytes — and Racket’s dialect is deliberately its own language rather than a minimal R7RS implementation, so portable Scheme code may need #lang r7rs and light adaptation.

Chez Scheme — The Compiler Everyone Borrows

Chez Scheme is a native-code compiler with a reputation that outruns its star count. It compiles Scheme to machine code with an aggressively optimised runtime, and its influence is visible everywhere: Racket’s core is Chez, and Idris 2’s default code generator targets Chez because it produces fast, predictable native executables.

Build it from source (the recommended path — there is no official container image):

1
2
3
4
5
6
sudo apt install build-essential libncurses-dev libx11-dev
git clone https://github.com/cisco/ChezScheme.git
cd ChezScheme
./configure --threads --installprefix=/usr/local
make && sudo make install
scheme --version

Compile a program to a standalone executable:

1
2
3
4
5
# Produce a native binary from a Scheme source file
echo '(display "compiled by Chez\n")' > hello.ss
scheme --script hello.ss
# Build a boot file for distribution with your application
scheme --program hello.ss
1
2
3
4
5
6
7
;; Chez ships a fast, well-documented library surface
(import (chezscheme))

(define (fib n)
  (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))

(time (display (fib 30)) (newline))

Where it wins: compile speed, runtime performance and a compact, embeddable runtime that a C host can link against. Cisco maintains it as production infrastructure, which is visible in the release cadence. Where it costs you: the package ecosystem is small compared to Racket’s or CHICKEN’s, there is no official image, and tooling assumes you are comfortable with the command line and a .sls library layout.

GNU Guile — The GNU Extension Language

Guile is the official extension language of the GNU Project. That single sentence explains its whole design: it is built to be embedded, to load code at runtime, to expose C functions to Scheme and Scheme functions to C, and to stay small enough to live inside long-running applications. GDB, LilyPond and Texinfo all extend themselves with Guile, and the Guix package manager is written in Guile from top to bottom.

Install from your distribution or build it yourself:

1
2
3
4
5
6
# Debian / Ubuntu (runtime + development headers for embedding)
sudo apt install guile-3.0 guile-3.0-dev

# From source (for a pinned version)
sudo apt install build-essential libgmp-dev libunistring-dev libffi-dev
# then: ./configure && make && sudo make install

Embed it in a C program:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <libguile.h>

static SCM
host_multiply(SCM a, SCM b)
{
  return scm_product(a, b);
}

static void *
run_guile(void *data)
{
  scm_c_define_gsubr("host-multiply", 2, 0, 0, host_multiply);
  scm_c_eval_string("(display (host-multiply 6 7)) (newline)");
  return NULL;
}

int
main(int argc, char **argv)
{
  scm_with_guile(&run_guile, NULL);
  return 0;
}

Compile it with gcc embed.c $(pkg-config --cflags --libs guile-3.0) -o embed.

Run a script:

1
2
3
4
5
6
7
#!/usr/bin/env -S guile -s
!#

(use-modules (srfi srfi-1))

(define (sum-squares lst) (reduce + 0 (map (lambda (x) (* x x)) lst)))
(format #t "~a~n" (sum-squares '(1 2 3 4 5)))

Where it wins: embedding, GNU integration, and a JIT-enabled bytecode VM that is more than fast enough for scripting and configuration logic. Where it costs you: documentation assumes you already know the GNU toolchain, there is no official container image, and its library culture is SRFI-driven rather than built around one big curated catalog.

Performance: What to Measure and How

The three implementations differ far more in compilation strategy than in language semantics, so the honest comparison is about workload shape.

WorkloadCharacteristic behaviourWhat to measure
Tight numeric recursionChez native code leads; Racket CS is in the same familyWall-clock on your actual algorithm, with and without type hints
Process startup for CLI scriptsGuile bytecode starts quickly; Racket’s platform initialises more stateCold-start time in a container, measured with hyperfine
Macro-heavy code generationCompile cost dominates at build timeBuild-time duration, not runtime
Long-running embedded interpreterGuile’s embedding API removes process overhead entirelyResident memory growth over hours of requests

Keep a benchmark file in your repository and run it under each implementation on your own hardware — architecture notes from someone else’s laptop are not a deployment decision.

Pitfalls, Portability and Migration Traps

  • “Scheme” is a family, not a language. R7RS-small covers the core, but module systems, record types, exception handling, hash tables and string handling differ between Racket, Chez, Guile and CHICKEN. Budget real porting time.
  • Racket’s #lang is a commitment. Idiomatic Racket code is not portable Scheme. If portability is a requirement, write #lang r7rs modules and test them on a second implementation from day one.
  • Chez has no package manager you should rely on. Vendor your dependencies as .sls libraries in your repository; upstream changes are easy to absorb and your build stays reproducible.
  • Guile’s embedding API needs careful thread discipline. scm_with_guile isolates the interpreter from the host’s threading model — never call Guile from arbitrary host threads without going through it.
  • Continuations interact badly with FFI and resource cleanup. First-class continuations are a superpower, but code that captures them across a foreign call can leak file descriptors or locks. Keep continuation-heavy code away from manual resource management.
  • Container images only exist for Racket. For Chez and Guile, build a small multi-stage image yourself: compile in a builder stage, copy the binary into a slim runtime stage.
  • Watch the licence of the implementation, not just the language. Chez Scheme uses the Apache 2.0 licence, Racket is MIT/APACHE dual-licensed, and Guile is LGPL-3.0-or-later — the last one matters if you link libguile into a proprietary host application.

For other Lisp-family deployments, see our guides to the Common Lisp web stack and the Clojure web framework comparison. If symbolic and logic-based programming is what drew you to Scheme, the Prolog engine comparison covers the other half of that tradition.

FAQ

Is Scheme still worth using in 2026? Yes, in three specific niches: scripting and extending existing software (Guile inside GNU tools), language implementation and macro research (Racket and Chez), and small compiled utilities where a tiny runtime matters (CHICKEN and Chez). It is a poor choice for teams that need a large hiring pool or a huge third-party library ecosystem.

Racket or Chez Scheme — which is faster? Racket’s main distribution has been built on Chez Scheme since Racket 8.0, so the two share a compiler core and land in a similar performance class. Chez gives you the compiler directly with less platform overhead and a much smaller footprint; Racket gives you the same core plus a standard library, package manager and IDE.

Can I embed Scheme in a C or C++ application? Yes, and Guile is the implementation designed for it: libguile provides documented C APIs for defining foreign functions, evaluating strings and calling Scheme from C. Chez Scheme can also be embedded, but you will be working closer to its build system.

Does Guile work outside the GNU ecosystem? Completely. It is a general-purpose Scheme with a bytecode VM and JIT, SRFI support, module system and web libraries. The GNU association simply means it is unusually well tested in long-running, embed-heavy applications.

How do I choose between Racket and Guile for a web service? If you want the fastest path to a working service with packaging and tooling, Racket. If your service is an extension of an existing C program, or you need to live inside a Guix deployment, Guile. Both handle HTTP fine; the difference is ecosystem fit, not raw capability.

Where does CHICKEN Scheme fit? When you want Scheme compiled to portable C with a small runtime — useful for vendoring into constrained environments or shipping a single static binary. Its eggs repository is genuinely large and the community is small but active.


💰 想测试你的市场判断力?我用 Polymarket 做预测市场交易——这是全球最大的预测市场平台,从大选结果到技术监管时间线,什么都可以押注。和赌博不同,这是真正的信息市场:你懂的信息越多,胜率越高。我靠预测技术相关事件的走向已经赚了不少。用我的邀请链接注册:Polymarket.com