← All skills
Nim Developer
Use when writing, reviewing, or optimizing Nim code — macros, memory management (ORC/ARC), C/C++ interop, error handling, generics, or cross-compilation.
About this skill
Use when writing, reviewing, or optimizing Nim code — macros, memory management (ORC/ARC), C/C++ interop, error handling, generics, or cross-compilation.
SKILL.md
nim-developer.SKILL.mdPlace it in your Syntic skills folder. For Syntic Code, install in your local skills directory, review the contents and run it in a controlled environment first.
---
name: Nim Developer
description: Use when writing, reviewing, or optimizing Nim code — macros, memory management (ORC/ARC), C/C++ interop, error handling, generics, or cross-compilation.
category: Languages
version: 1.0.0
tools: []
---
# Nim Developer
Expert guidance for building efficient, readable Nim applications that compile to optimized native code, using Nim's macro system, memory management options, and C/C++ interoperability.
## Metaprogramming with Macros
- Use templates for simple, hygienic code substitution; templates do not evaluate arguments multiple times.
- Use macros to inspect or transform the AST via `NimNode`, manipulating it at compile time.
- Use `quote do:` blocks inside macros to construct AST fragments with backtick interpolation.
- Implement domain-specific languages with macros: custom syntax for configuration, routing tables, or state machines.
- Use `{.pragma.}` annotations to attach metadata to types, procs, and fields; read pragmas in macros with `hasCustomPragma` and `getCustomPragmaVal`.
## Memory Management Strategies
- Use `--mm:orc` (Nim 2.x default) for most applications: deterministic reference counting with cycle collection.
- Use `--mm:arc` for real-time applications where cycle-collection pauses are unacceptable; break cycles manually with `=destroy` or weak references.
- Use `--mm:none` for embedded targets with no heap allocation, relying on stack allocation and `array` types.
- Minimize allocations in hot paths; use `openArray` parameters to accept arrays and sequences without copying.
- Use `sink` parameters to transfer ownership and avoid copies; use `lent` for read-only borrowed access.
## C and C++ Interoperability
- Use `{.importc.}` and `{.header.}` pragmas to call C functions directly; Nim compiles to C, so interop is zero-cost.
- Wrap C structs with `{.importc, header: "mylib.h".}` on Nim object types, matching field order and types exactly.
- Use `{.emit.}` for inline C/C++ code when pragma-based interop is insufficient.
- Generate Nim bindings from C headers with `c2nim` or `nimterop`, and review generated bindings for correctness.
- Use `{.compile: "file.c".}` to include C source files directly in the Nim build.
## Error Handling
- Use exceptions for recoverable errors; define custom exception types inheriting from `CatchableError`.
- Use `Result[T, E]` from `std/results` for functional error handling without exceptions, chaining with the `?` operator.
- Use `{.raises: [].}` effect tracking to document and enforce which exceptions a proc can raise.
- Handle resource cleanup with `defer` blocks; use `try/finally` for complex cleanup sequences.
- Never catch `Defect` exceptions — defects indicate programming errors (index out of bounds, nil access) and should crash.
## Type System Features
- Use distinct types to prevent mixing semantically different values: `type Meters = distinct float64`, `type Seconds = distinct float64`.
- Use object variants (discriminated unions) for type-safe sum types with `case kind: enum of`.
- Use generics for type-parameterized containers and algorithms, constrained with concepts.
- Use concepts for structural typing: define required operations without requiring inheritance.
- Use `Option[T]` from `std/options` for nullable values; pattern match with `isSome` and `get`.
## Project Structure
- Use Nimble for package management; define dependencies in `project.nimble` with version constraints.
- Organize source under `src/`, with `src/project.nim` as the main module and `src/project/` for submodules.
- Place tests in `tests/` with filenames prefixed by `t`: `tests/tparser.nim`, `tests/tnetwork.nim`.
- Use `nim doc` to generate HTML documentation from `##` doc comments on public procs.
- Cross-compile by specifying target OS and CPU, e.g. `nim c --os:linux --cpu:arm64 src/project.nim`.
## Performance Optimization
- Compile with `-d:release` for production; this enables optimizations and disables runtime checks.
- Use `--passC:"-march=native"` for architecture-specific optimizations on known hardware.
- Profile with `nimprof` or external tools (perf, Instruments); use `--profiler:on` for Nim's built-in sampling profiler.
- Pre-allocate `seq` capacity with `newSeqOfCap` when the final size is known, to avoid repeated reallocations.
- Use bit operations and manual loop unrolling for performance-critical numeric code.
## Before Completing a Task
- Confirm the code compiles cleanly with hints and warnings on, using a release build (`-d:release`).
- Confirm the full test suite (`nimble test`) passes.
- Check that `{.raises.}` annotations are accurate on all public API procs.
- Verify cross-compilation targets build successfully if the project supports multiple platforms.
Install
Syntic App
- 1Create a dedicated folder for this skill in your local skills library.
- 2Place SKILL.md into that folder.
- 3Restart Syntic and invoke this skill on matching tasks.
Syntic Code (CLI)
- 1Save SKILL.md in your local Syntic Code skills directory.
- 2Keep related files in the same skill folder.
- 3Run in a safe environment and validate outputs.