HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
nim-lang
c2nim
Nim2018–2025
nim-lang / c2nim

c2nim

c2nim is a tool to translate Ansi C code to Nim. The output is human-readable Nim code that is meant to be tweaked by hand before and after the translation process.

8Distinct people
8Mentions
0Explicit recommenders
528GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

c2nim is a tool to translate Ansi C code to Nim. The output is human-readable Nim code that is meant to be tweaked by hand before and after the translation process.

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year8 dated mentions

Observed mentions: 2018-03-02 07:13:30 UTC to 2025-09-01 20:30:06 UTC.

0122018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20182019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC101
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC000
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC101
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC211
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC202
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC101

What Hacker News says

8 sources
This is a bit controversial, but in my opinion, just manually write bindings for the API surface you care about. There are tools to help automate the process ([c2nim](https://github.com/nim-lang/c2nim), [futhark](https://github.com/PMunch/futhark)), but these tools are mostly for C. Theoretically if you want to import a large C++ API (e.g. if you were importing Google's C++ codebase*), you could do so with libclang. I was working on an alternative to c2nim that supported Objective-c and C++, which used libclang, but it's currently in my project graveyard. If you're expecting a @cImport from Zig, then the closest you have to that is tools mentioned above to help with the process. * to be clear, I understand why Google does not want to use Nim instead of creating a new language (Carbon). i.e. readable code output, full control of the compil
Read the rest
er and language design, etc. The amount of manual work to write bindings is minimal, i.e. you can do so simply by declaring a prototype for a procedure and then appending `{.importcpp, header: "<path>".}`, the same for types. And then compile with `nim cpp`. Compare the way you wrap libraries in Python, Nim requires so much less work - and yet the Python community wraps every C/C++ library you can think of. Again, in my opinion, if you really want a library: wrap it yourself (ideally the subset you need) or rewrite it in Nim. Also, most of the libraries you have listed have bindings already: - Qt: https://github.com/jerous86/nimqt or [seaqt](https://forum.nim-lang.org/t/12709) - ImGUI: https://github.com/nimgl/imgui - SFML: https://github.com/oprypin/nim-csfml - SDL: https://github.com/nim-lang/sdl2 - sokol: https://github.com/floooh/sokol-nim If there's a popular enough C or C++ library, it's probably already wrapped, especially within the gamedev community.
In A review of Nim 2: The good and bad with example code
Also on the game development front, I maintain a raylib wrapper https://github.com/planetis-m/naylib As long utilities like c2nim https://github.com/nim-lang/c2nim exist, it's trivial to create bindings of C/C++ libraries. One thing I want to experiment more is making it more automatic by writing a callback exposed by c2nim that transform the generated code using Nim's AST. But regardless in that project I was able to write safe language abstractions on top of the bindings that provide a more native experience. It has scope-based memory management, generics and ... function/enum overloading.
In I learned seven programming languages
Ugh, the C syntax makes it so hard to parse, humans or machine. I recently submitted a PR for the `c2nim` import tool to handle double function pointers. I didn't actually understand the C code until I got the transpiler working despite cdecl.org: // posix signal void(*signal(int, void (*)(int)))(int); in Nim becomes: var signal*: proc (a1: cint; a2: proc (a1: cint)): proc (a1: cint) Well I'm 99.5% certain at least. Even now I'm uncertain of the C syntax. And I've not been bold enough to test 3rd order C function pointers. I figure that's probably C code you don't wanna touch if possible. https://github.com/nim-lang/c2nim/blob/11f2c5363dfe7e8c7c8ce... The other annoying one is that "signed" and "unsigned" are basically adjectives, but "long" can be both a type and a modifier. So it's difficult to parse unless you're the tar
Read the rest
get C compiler. Technically you can, but you have to use backtracking.
In Checked C
Sorting out your edit/IDE/lib situation & re-learning is part of any PL switch in my experience (& just varies). Trade offs abound in most things. D is undeniably syntactically closer to C if that is the priority. I knew people in the initial Java era who insisted their next PL had to look like C. I know others who prefer Pythonic brevity and Nim is even more brief & to the point in many ways. Compatibility-wise, Nim can also just `emit` C/C++/Javascript (like D|Nim can just emit inline assembly) - arguably max compatibility that can even work with arbitrary non-portable backend compiler pragmas, `__int128` extensions, etc. OTOH, that also ties it to limitations of backends. Possibly relevant is https://github.com/nim-lang/c2nim & https://github.com/PMunch/futhark & the rather old/probably partly stale in both columns https://github.
Read the rest
com/timotheecour/D_vs_nim . There are many choices in Nim. Sometimes https://en.wikipedia.org/wiki/The_Paradox_of_Choice can be a real problem - in both software or in life - and at many, many levels. :) I am not trying to challenge your own priorities or push choices on you, but to add information others may be unaware of.
In Zig-style generics are not well-suited for most languages
Now if only a full binding generator for C and C++ headers to Nim was done (the reverse), the language would really be cooking! "What do you mean, Nim has two of these already?" Yeah, I know, and -- not to hurt anyone's feelings -- but: they kind of suck. And there's no way I see them able to be extended to do the job fully, based on the way they're currently built. Those are some bold claims to make! So before I get stoned to death (no offense to the authors, I am grateful that they exist and have used them both) let me attempt an explanation and back up these statements. --- To start off, the two tools available are "c2nim" and "nimterop". c2nim is a Nim official library, while nimterop is a community library. https://github.com/nim-lang/c2nim https://github.com/nimterop/nimterop To preface this: I've spent a fair amount of time on
Read the rest
the "codegen of bindings for interop from C/C++ headers" problem. The first thing I did was reach out to people who spent months or years on this problem and ask them what worked and what didn't. (I had no clue where to start and figured lots of smart people have done this before) Consistently, what I heard was (roughly): "If you want to programmatically interact with information about C/C++ units, you want to use the LLVM/clang ecosystem. You're going to think you can do what you want from 'libclang', the C API. But what you'll find out after sinking months of your time is that libclang DOESN'T expose enough info about the AST for certain scenarios, and there is ABSOLUTELY ZERO WAY to get it. So you'll need to use libTooling, which is C++, and has the full AST available." I've found this to be true, with the exception that a few people have taken to "augmenting" libclang with extra bindings to libTooling functions or other C++-only methods. Most notably is Tanner Gooding & Co's "libClangSharp" from the Microsoft "ClangSharp" project, and PathogenDavid's "Biohazrd" libraries (which again are a sort of enhanced fork based on ClangSharp): https://github.com/microsoft/ClangSharp # See "/sources/libClangSharp" https://github.com/InfectedLibraries/Biohazrd Okay so with that out of the way, my long-winded point is: - c2nim is a custom C lexer/parser written in Nim, with zero support for C++ - nimterop uses tree-sitter, which isn't bad but it's certainly no "libTooling" Neither tool supports C++, and edgecases (in either text or syntax) will still outright break them/they don't know how to handle. I had one where an unprintable unicode character caused c2nim to freeze indefinitely. Nimterop is also dead as far as I understand -- last active commit period was about ~1 yr ago. I'm hard to convince to the path to success here doesn't involve leaning on the collective decades of man-hours of engineering put into clang/LLVM. C++ is a nightmare of a specification, a veritable cluster-fuck of complexity. --- As a side note, I've had the opportunity to speak to one of the Nim maintainers (Timothee Cour) about this and the future here, and he's expressed interest in having a good story for easy type-safe C++ interop via binding generation and also believes it's important. So hopefully this is something we'll see pop up eventually. Maybe I'll take a crack at myself using ClangSharp (or it's XML output format, using TypeScript/Python to munge the XML and spit out code) but there aren't enough hours in a day to do all the interesting things =(
In Genny – Generate Nim library bindings for many languages
Yes, if the target is C++ then the whole output will be in C++, including code for GC operations, so you can directly inspect how this is translated. You can actually choose between several GCs for different needs: https://nim-lang.org/docs/gc.html It's worth mentioning that by default all types in Nim are stack allocated, and you have full manual memory management to the same level as C/C++ but with better type safety and less boilerplate. The GC is only used when you tag a type as `ref`, in strings, and the 'vector' dynamic list type, `seq`. The newer GC, ARC (not related to Swift's ARC), is similar to RAII - scope based, non-atomic, deterministic, shares memory between threads but not stop-the-world, and uses move semantics: https://nim-lang.org/docs/destructors.html This makes the GC a nice to use addition for resource management but
Read the rest
not a fundamental requirement or speed limitation. In my experience the default (thread-local refc + cycle collection) GC is very performant already, but it's straightforward to write code that works entirely on the stack, or create objects that wrap manual heap allocs, or use custom external memory allocators. Passing `--gc:none` removes the GC entirely from the compilation target, for example if you're working with very constrained embedded devices with the caveat that less of the stdlib is available (currently). The ARC GC (doesn't handle cycles unlike it's sibling ORC) is aiming to be lean enough to be used in hard realtime and memory constrained embedded systems. For hard realtime though I'd expect most people would just manually manage their types anyway on the heap or stack. If you're doing interop between Nim and C++ and want Nim's GC to manage types that you're passing directly to pure C++ code, you can tell the GC that the data is still being used with GC_Ref() or not with GC_Unref(). There are a few libraries for C/C++ interop, such as: https://github.com/nimterop/nimterop Personally in this case I would probably just manually allocate memory memory in Nim or C++ and not use GC'd types across boundaries for clarity if nothing else, still it's an option if your design requires it. Finally, there is a tool to help auto-translate C/C++ to Nim with the c2nim tool: https://github.com/nim-lang/c2nim and docs: https://github.com/nim-lang/c2nim/blob/master/doc/c2nim.rst
In Std::visit is everything wrong with modern C++ (2017)
It can target everything that C89 can target, but it may require some additional steps like writing the Nim interface code for target specific system libraries etc. There are also tools to help with this, but I prefer to write the Nim interface to existing C code myself. A thread about the added Android support: https://forum.nim-lang.org/t/3098 An old article about targeting IOS: http://www.thomasdenney.co.uk/blog/2015/1/27/nim-on-ios/ Also have a look at the following list: https://forum.nim-lang.org/t/2670 (nimx, a cross-platforn GUI library, seems to support Android/IOS) The following shows how to interface with ObjectiveC code / libraries: https://github.com/jangko/objc (Of course, if they are not already available, you will have to create the Nim interface to the IOS libraries yourself) One of the tools that can be used to create Ni
Read the rest
m interface code from existing C header files: https://github.com/nim-lang/c2nim
In Nim language v0.18.0 released

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.