C2TypeScript is a partial-coverage C-to-TypeScript translator and proof-of-concept. It is not a universal C17 translator. It handles a meaningful subset of real-world C code (demonstrated below by ports of several published C libraries), but it does not cover the full C17 language, the full C standard library, or the full range of real C codebases.
The translator emits TypeScript that compiles on Node ES2022+ and aims to produce the same observable output as the original C program for the inputs it supports. Output is engineered for refactorability: every C-only concept (pointers, value-semantic structs, manual memory, bitfields, unions) is emitted at a marked bridge boundary using a descriptively-named runtime helper, so a human or AI agent can replace foreign encodings with idiomatic TypeScript in isolated passes.
This repository is an inactive experimental snapshot. I am not actively developing C2TypeScript, I do not have plans to finish it, and it should be read as an experiment in what is possible with C-to-TypeScript translation rather than as a maintained compiler project.
v0.1 - inactive proof-of-concept, partial C17 coverage. The translator works end-to-end on small-to-medium real-world C libraries (a handful of these have been ported and are linked below). Larger C codebases - notably the Lua 5.4 interpreter at ~20,000 lines - translate but exhibit runtime divergence. Full C17 conformance and full real-world generality were not reached and are not planned.
Treat C2TypeScript as a research artifact: useful for studying one approach to preserving C semantics in TypeScript and for inspecting the demonstrated translations, not as a general C compiler replacement or a maintained dependency.
Each of these is a published TypeScript port of a real C library, produced through C2TypeScript. The links below point at the actual ts-* repositories:
| Source C library | Approx. C LOC | TypeScript port |
|---|---|---|
| cJSON | 7,000 | ts-cJSON |
| antirez/sds | 3,000 | ts-antirez-sds |
| tiny-aes-c | 1,000 | ts-tiny-aes |
| Cyan4973/xxHash | 2,000 | ts-xxhash |
| picohttpparser | 700 | ts-picohttpparser |
| chibi base64 | 400 | ts-chibi-base64 |
| tiny-regex-c | 500 | ts-tiny-regex-c |
| jsmn | 500 | ts-jsmn |
| parson | 3,500 | ts-parson |
| FastLZ | 700 | ts-fastlz |
Additional smaller hash / crypto / encoding libraries have also been translated; see translated-projects/ for the full set of 49. Thirteen of them are published on npm and take this repository as their repository target.
- Larger C codebases (for example the Lua 5.4 interpreter, ~20,000 LOC) translate to clean TypeScript but exhibit runtime divergence from the original. This is a known unresolved gap.
- Significant parts of C17 are not covered. Several constructs are either unimplemented or rejected with a diagnostic rather than translated.
- Several POSIX / system-API surfaces are stubbed or partial.
- C++ source is out of scope for this translator; a separate C++20 translator sharing the same compiler core lives in
translators/cpp2typescript. - Lua source is out of scope for this translator; a separate Lua 5.4 translator lives in
translators/lua2typescript.
When an input falls outside current coverage, the translator fails closed with a deterministic diagnostic rather than emitting broken output.
This repository is not presented as a polished npm package or maintained CLI. The commands below describe the intended shape of the prototype interface, but expect rough edges in the checked-in snapshot.
Translate a single C file:
npx c2typescript --input path/to/program.c --output path/to/program.tsTranslate a project tree using a compile-commands database:
npx c2typescript --project path/to/project --output path/to/outRun the translated program:
node path/to/program.tsimport { Emitter, parseAST, mapType } from "c2typescript";
const ast = await parseAST({ source: "path/to/program.c" });
const emitter = new Emitter({ /* options */ });
const ts = emitter.emit(ast);See UNIVERSALITY_CONTRACT.md for the per-construct support matrix and the conditions that would have been required before making any universality claim.
C17 is a complete, published specification. The experiment enumerated coverage against ISO/IEC 9899:2018 itself rather than being driven only by accumulated test failures:
- Every C17 §6 and §7 construct is enumerated in a cell catalogue.
- Each cell is either implemented or rejected with a deterministic diagnostic; no construct is silently accepted-and-broken.
- Real-world translations confirm specification work; they do not drive it.
The resulting enumeration is partial. The intent of this approach was that, once a cell was closed, the translator should work on previously unseen code that exercises that cell - not only on the test fixtures used during development.
C2TypeScript output follows ten commitments:
- Correctness first. Same observable output as the original program for inputs the translator supports.
- Localised bridges. Foreign concepts emit at one-line marked sites:
// BRIDGE: <concept>. - Descriptive helper names.
cptr_read_null_terminated_string, not_rnts. - Pattern consistency. Every C pointer emits the same way; every struct-by-value emits the same way.
- Source identity preserved. Identifiers, scope structure, control flow, and comments come through verbatim.
- Rich types. Every parameter, return, and variable carries a precise TypeScript annotation.
- No clever optimisations. One C statement maps to one TypeScript statement where possible.
- Explicit imports. Every runtime helper appears as a visible
import; the imports are the manifest of which C concepts the program uses. - Documented choices. Where translation picks one encoding among several correct options, an inline comment records the choice and the hint for refactoring.
- Source maps. Each emitted TypeScript range maps back to the originating C AST node.
The output is a base layer that humans or LLMs can refactor toward idiomatic TypeScript in a separate, mechanical pass, rather than a finished idiomatic translation that has already collapsed information the refactorer would need.
C2TypeScript emits to a small set of runtime libraries that model C semantics TypeScript does not natively express. These appear in the vendor/ tree of this repository under literal names:
vendor/c-pointer-layout/- the C pointer model (CPtras{buf, off}), heap, numeric primitives, struct layout.vendor/c-stdlib/- C standard library:printf,string.h,stdlib.h,math.h,ctype.h,time.h.vendor/posix-runtime/- POSIX-shaped surfaces: VFS, environment, process, streams, clock.vendor/browser-runtime/- browser surfaces (SDL/Canvas, input, audio, storage, network) for C libraries that target the browser.
Each runtime library is its own self-contained TypeScript package. The translator emits import statements that reference these by descriptive name.
The repository also vendors a few translator-support libraries under similarly literal names: clang-frontend/ (Clang AST ingestion), source-mapping/ (translation-unit-to-output range mapping), compile-db/ (compile-commands ingest), dep-graph/ (dependency resolution), conformance/ (audit and rejection diagnostics), and validation-harness/ (parity testing).
This repository holds three related source-to-TypeScript translators that share a common compiler core, plus the translation outputs produced by the C one.
| Path | Contents |
|---|---|
src/, vendor/ |
C2TypeScript itself - the C17 translator described above |
translators/cpp2typescript |
Cpp2TypeScript - C++20 translator, v0.1.0-pre snapshot |
translators/lua2typescript |
Lua2TypeScript - Lua 5.4 translator, v0.1.0-pre snapshot |
translated-projects/ |
49 C libraries translated to TypeScript by C2TypeScript |
The two sibling translators were separate repositories until 2026-09-05 and were merged here with their history intact. Like C2TypeScript they are inactive experimental snapshots, generated from an internal source tree via each directory's MANIFEST.json; none of the three translators is published to npm.
| Attribute | Status |
|---|---|
| Source language | C17 (ISO/IEC 9899:2018) - partial coverage |
| Target language | TypeScript |
| Target runtime | Node ES2022+ |
| Data model | Explicit ABI / layout declared per translation (pointer size, integer sizes, alignment, endianness) |
| C++ | Out of scope here; see translators/cpp2typescript |
| Lua | Out of scope here; see translators/lua2typescript |
| Unsupported constructs | Enumerated; fail closed with deterministic diagnostics |
See UNIVERSALITY_CONTRACT.md for the canonical per-attribute completion state.
MIT - see LICENSE. Matches the licensing of the ts-* translation outputs in translated-projects/ and of the sibling translators in translators/.
Scott Moore.