Skip to content
Agentmart
Submit a tool

nim-c-wrappers

Turn low-level C FFI bindings into an idiomatic Nim API, with safer types, cleaner module boundaries, resource management, callbacks, enums, bitflags, and…

Skill by Vyrnexis

IndexedMIT★ 4
Write a review

Chalk Labs

Need help deploying nim-c-wrappers?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/vyrnexis-nim-c-wrappers

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Turn low-level C FFI bindings into an idiomatic Nim API, with safer types, cleaner module boundaries, resource management, callbacks, enums, bitflags, and exception-based error handling. Use when building a high-level Nim wrapper around a C library or improving the usability of existing raw bindings.

Use cases: backend

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/nim-c-wrappers

What's inside

Skill name
nim-c-wrappers
Description
Turn low-level C FFI bindings into an idiomatic Nim API, with safer types, cleaner module boundaries, resource management, callbacks, enums, bitflags, and exception-based error handling. Use when building a high-level Nim wrapper around a C library or improving the usability of existing raw bindings.
License
MIT
Instructions
111 lines in SKILL.md · view on GitHub

Files (6)

  • SKILL.md
  • callback_pattern.md · references/
  • enum_and_bitflags.md · references/
  • module_layout.md · references/
  • move_only_resource.md · references/
  • rc_resource.md · references/

SKILL.md (first lines)

# Nim C Wrappers

## Rules

### Architecture

- Use a **two-layer design**: raw FFI layer (ABI-faithful) + ergonomic Nim layer (safe, idiomatic). Keep the raw layer thin and stable.
- Split modules by library domain. Mirror the C header structure for large libraries.
- Centralize shared types in a `lib_raw_types` module to avoid cyclic imports.
- Export raw symbols only for advanced users; re-export selected symbols from ergonomic modules.

### Raw FFI Layer

- Use `importc` with `cdecl` (or `stdcall` if the library requires it). Prefer `{.push callconv: cdecl, importc.}` blocks for shared conventions.
- `header` declares linker-resolved imports; `dynlib` loads symbols at runtime. Do not combine them on one proc. Guard library names with `when defined(windows):` etc.
- **Never reorder struct fields.** Use `object` in C field order. Add `packed` only if C headers specify packing.
- Use `incompleteStruct` and list only needed fields to reduce ABI risk.
- For C enums, use `distinct` integer types + `const` values. Do not use Nim `enum` in raw bindings. Find actual enum values in C headers—do not guess.
- For bitflags, use `distinct` integer types with bitwise helpers. Do not use `set[Enum]`.
- Map C macros: numeric → `const`; function-like → `template`; use `inline proc` when arguments should evaluate once.
- Keep pointer types as C intends — do not convert them in the raw layer.

### Type Mapping

| C Type | Nim Type | Notes |
|--------|----------|-------|
| `char` | `cchar` | Platform-dependent signedness |
| `signed char` | `cschar` | Always `int8` |
| `unsigned char` | `uint8` | Safer default spelling; avoid relying on `cuchar` status across Nim versions |
| `short` | `cshort` | Always `int16` |
| `unsigned short` | `cushort` | Always `uint16` |
| `int` | `cint` | Always `int32` |
| `unsigned int` | `cuint` | Always `uint32` |
| `long` | `clong` | ABI-sized (4 on Win64, 8 on LP64) |
| `unsigned long` | `culong` | ABI-sized |
| `long long` | `clonglong` | Always `int64` |
| `unsigned long long` | `culonglong` | Always `uint64` |
| `size_t` | `csize_t` | Alias for `uint` |
| `intptr_t` | `int` | Pointer-sized signed |
| `uintptr_t` | `uint` | Pointer-sized unsigned |
| `float` | `cfloat` | Always `float32` |
| `double` | `cdouble` | Always `float64` |
| `long double` | `clongdouble` | Limited codegen support |
| `void*` | `pointer` | Untyped |
| `T*` | `ptr T` | Nullable |
| `T**` | `ptr ptr T` | |
| `char*` / `const char*` | `cstring` | NUL-terminated |
| `char**` | `cstringArray` | `ptr UncheckedArray[cstring]` |

Struct types: `object` in C order. Fixed arrays: `array[N, T]`. Pointer+length: `ptr T` + `csize_t`. Raw buffers: `ptr UncheckedArray[T]`. Opaque handles: `pointer` or `ptr OpaqueObj` (empty object).

### Ergonomic Layer

- In `=destroy`, explicitly call `=destroy` on owned nested GC-managed fields (string, seq) after releasing C resources.
- Define ownership hooks in the **same module** as the type. Cross-module hook definitions are a compile error.
- Raise exceptions (IOError, ValueError, etc.) for C errors — do not return result wrappers that only carry ok/kind/message.
- Do not create custom exception types unless callers handle them differently.
- Catch errors only at translation boundaries (C return code → Nim exception, or exception → domain result). Let exceptions propagate otherwise.

### Naming

- In raw bindings, match C identifier names directly.
- `importc` without an explicit string resolves the C symbol from the Nim name.
- Strip redundant C prefixes (LIB_, foo_) in the ergonomic layer.
- Keep raw constant names in C style (e.g., `CURLE_OK`).
- When a C identifier collides with a Nim keyword, rename the Nim identifier and use `importc:` to map to the original C name.

### Callbacks

- Declare callbacks as plain C-callable procs such as `proc onEvent(code: cint; userData: pointer) {.cdecl.}`.
- Pass closure state through `userdata` via `rawProc`/`rawEnv`. See `references/callback_pattern.md`.

### Verification

- Add `static: doAssert sizeof(T) == N` and `offsetOf` checks in tests to verify struct layouts.
- Test ABI with compile + link + smoke test + runtime checks.

## Workflow

1. **Read the C API.** Identify structs, enums, functions, callbacks, and ownership semantics.
2. **Map types.** Use the type table. Verify sizes with `static: doAssert sizeof`.
3. **Write raw bindings.** One module per C header or subsystem. Centralize shared raw types to avoid cycles. Use `importc`, correct calling convention, `packed` only when C specifies it. Use typed integer aliases for enums.
4. **Write ergonomic wrappers.** Add destructors for owned resources (move-only or RC). Raise exceptions for C errors. Re-export only the intended public surface. Strip prefixes.
5. **Test.** Compile check → link check → smoke test → ABI sizeof/offset asserts → runtime ownership tests.
6. **Iterate.** Add missing APIs as needed. Keep raw layer stable.

## Common Mistakes

| Mistake | Why it's wrong |
|---------|----------------|
| Passing Nim `string` directly to `char*` parameter | Type mismatch; use `.cstring` |
| Using `seq` where C expects stable pointer | `add()` can reallocate, invalidating the pointer |
| Reordering struct fields | Breaks ABI layout, causes garbage values |
| Using Nim `enum` for C enum values | ABI incompatibility; use typed integer aliases |
| Adding enum or constant values without inspecting headers | Find actual enum values in C headers, do not guess |
| Passing closures as C callbacks | C expects plain function pointers, not GC closures |
| Storing `cstring` beyond the call | `cstring` from `string.cstring` dangles after the source is freed |
| `=dup` body using `result = src` in RC pattern | May trigger implicit `=copy` instead of `=dup`; use field-by-field assignment |
| Wrong calling convention | Causes crashes at call sites |

## References

- `references/move_only_resource.md` — A move-only wrapper for one owner of a C handle.
- `references/rc_resource.md` — A reference-counted wrapper for shared C resource ownership.
- `references/callback_pattern.md` — C callbacks with userdata, captured Nim state, and lifetime
  management.
- `references/enum_and_bitflags.md` — Distinct-integer wrappers for non-contiguous enums and
  bitwise flags.
- `references/module_layout.md` — Separating raw FFI from an ergonomic API in two modules.

From Vyrnexis/nim-agent-template, MIT.

More from Vyrnexis/nim-agent-template

Signals

Stars
4
Forks
2
Open issues
0
Last commit (this folder)
Aug 20, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from Vyrnexis

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get nim-c-wrappers running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying nim-c-wrappers?

CallGet help
Cite this page

nim-c-wrappers skill. Agent Mart. https://agentmart.dev/skills/vyrnexis-nim-c-wrappers (last updated 2026-10-24)