SELECT 1
Entry 024Tue 2026.11.03
One launch a day. Picked, run, explained.

Tue 2026.11.03

Jik: catching memory errors without a garbage collector

Today's pick: Jik

Jik is a product that manages a program’s memory without a garbage collector. It is a programming language that compiles to C. Values such as strings and structs go into regions, and freeing a region frees the values in it.

It is today’s pick because its compiler catches memory errors without a garbage collector.

exit 0Ran itIt works. The compiler rejected code that referred to a value in the wrong region.
Found on
Show HN
Built with
C, Jik

The problem

In languages like C, you allocate and free memory yourself. This leads to mistakes such as using memory after freeing it or forgetting to free it. Languages with a garbage collector prevent these mistakes, but at run time the collector spends time finding and freeing unused memory.

In the README, the maker says Jik avoids both garbage collection and manual heap allocation. The official Go guide to the garbage collector says every Go program ships with a runtime library. Its garbage collector finds memory that is no longer needed and recycles it. The same guide says the garbage collector uses physical memory and CPU time. Using less of one means using more of the other.

How it solves it

Jik was posted on Hacker News as a Show HN on November 2, 2026. Jik code is translated to C, then compiled with clang or gcc. Composite values such as strings, vectors and structs are allocated in regionA unit of memory that holds values allocated together, so they can all be freed at once instead of one by one.. Every function has a local region, and when the function returns, the region and its values are freed together.

The caller passes a region as an argument. The function allocates its return value in that region. The compiler checks that the values passed in one call are in the same region. This keeps a longer-lived value from pointing at a value in a region that is freed earlier. The compiler itself is written in Jik. The repository includes a seed compiler written in C that builds it.

What is different

The first difference is when memory is reclaimed. Jik frees a function’s whole region when the function returns. Unlike in Go, nothing searches for memory to reclaim at run time. The tradeoff is that a region’s memory is not freed before its function returns. Values allocated inside a long loop are not freed when the loop ends.

The second difference is how memory safety is checked. A C compiler accepts code that points at freed memory. Jik’s compiler rejects a function that returns a value from its local region. It also rejects a call that stores a local value in a struct from another region. The tradeoff is that the programmer passes a region argument for each result. The values passed in one call must share one region. The compiler proves that functions which only read values are safe, so they are exempt from this rule.

How it was built

  • The repository has 207 commits from April 25 to November 2, 2026, all by one person. No commit has a Co-authored-by trailer.
  • Jik is in beta (v0.1.0-beta.1), and its known limitations are listed in docs/known-issues.md.
  • There are separate tests for the seed compiler in C and for the Jik compiler.

Running it

I built the repository with clang and followed the README’s commands on a 4-core virtual machine.

  1. Build. make finished in 16 seconds, and the compiler binary was 927 KB. The C compiler printed 238 warnings on the generated C.
  2. Tests. make test passed all 13,036 checks in 14 seconds.
  3. Region checks. The compiler rejected a function that returned a struct from its local region. It also rejected a call that stored a function’s local string in a struct from another region. Passing a string literal directly worked. According to the documentation, the compiler allocates such a literal in the struct’s region.
  4. Memory in loops. A loop in main that turned 2,000,000 integers into strings grew main’s region to 96 MB. Peak memory use was 97.8 MB. When I moved the work into a function called on each iteration, main’s region stayed at 66 KB and peak memory use was 11.1 MB. Measured once each, the loop in main took 0.14 seconds and the version with function calls took 0.25 seconds. The repository’s memory management page and known issues page say nothing about allocating in loops.
  5. self-hostingWriting a compiler in the language it compiles, so the compiler can build itself.. make test-bootstrap-full starts from the seed compiler and builds the Jik compiler three times in a row. Each build uses the compiler from the previous build. It finished in 57 seconds, and the second and third builds generated the same C code. Rebuilding the compiler with itself no longer changes its output.
jik error: cannot return local allocation
      --> bad_return.jik:7:12
jik error: region mismatch
      --> bad_store.jik:11:15
    = all storing/returning call arguments must belong to the same region

Not checked

  • Calling C libraries. Build the example game with the Raylib bindingA declaration that links a function written in another language to a name and type in this language, so you can call it. in jik-packages, the Jik package repository. Raylib is a game library written in C.
  • Windows. According to the maker, Windows x64 is also a tested platform. Build with gcc there and run make test.

Verdict

It works. The compiler rejected code that referred to a value in the wrong region. But values allocated inside a loop stay until the function returns, so memory use grows with each iteration. It is worth trying if you need a safer alternative to C without a garbage collector.

Getting started

  1. git clone https://github.com/jik-lang/jik && cd jik
  2. make
  3. ./jik run examples/hello.jik
You need
Make and either clang or gcc. Building a Jik program also uses clang or gcc
Cost
Free under the MIT license.

The maker says Jik is in beta and still expects bugs and language changes.

Steps select 1 ran.

Progress

  1. Day 3Upcoming
  2. Day 7Upcoming
  3. Day 15Upcoming
  4. Day 30Upcoming
  5. Day 90Upcoming
  6. Day 180Upcoming
  7. Day 365Upcoming