nim-code-organization
Skill4 starsChanged 3 months agoMITView on GitHub
Organize Nim modules and multi-step workflows with explicit state ownership, cohesive boundaries, narrow exports, and structured orchestration. Use when refactoring a large Nim file, splitting logic across modules, designing parser-style stateful code, or simplifying nested helpers and hidden mutable state.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- planetis-m/skillsword for word, first seen Jul 16, 2026
Other versions1 project uses a version of this.
Word for word · 1
- planetis-m/skills★ 59100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository18 other files it gives its agents.
- atlas-package-clonerSkill
- buildSkill
- docs-genSkill
- format-codeSkill
- nim-api-designSkill
- nim-c-bindingsSkill
- nim-c-wrappersSkill
- nim-debuggingSkill
- nim-defect-analysisSkill
- nim-doc-commentsSkill
- nim-error-handlingSkill
- nim-fuzzingSkill
- nim-mcp-toolsSkill
- nimonypluginsSkill
- nim-ownership-hooksSkill
- nim-style-guideSkill
- nim-testingSkill
- run-testsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. About 0 are common, 9 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 14
Use ordinary locals when a workflow fits clearly in one proc.
- Distinctive: line 15
When independently meaningful operations must preserve one invariant, collect that state in a named object and pass it explicitly.
- Very specific: line 17
Start with a plain object passed by var.
- Distinctive: line 27
Keep a short, one-use sequence in its driver when extraction would only move lines elsewhere.
- Distinctive: line 28
Put helpers at module scope when several phases use them or they stand on their own.
- Distinctive: line 29
Use a nested proc for logic local to one caller or for an intentional closure.
- Distinctive: line 40
Keep orchestration state and helpers private unless another module is meant to use them.
- Very specific: line 41
Do not use {.define.}/{.undef.} to scope behavior across modules.
- Distinctive: line 45
Keep the normal path structured so its invariants remain visible.
- Very specific: line 47
Use method when runtime subtype dispatch is part of the design, rather than as the default way to divide orchestration steps.
- Distinctive: line 52
When the caller drives consumption piecewise, keep the cursor and lifecycle state in the object's fields so it survives between calls.
- Distinctive: line 65
Use locals for one clear proc, a plain object for operations preserving one invariant, and a reference only for intentional identity or …
- Very specific: line 75
Use direct calls and case for closed behavior.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Nim Code Organization
Choose the smallest structure that exposes the real workflow.
Rules
State ownership
- Use ordinary locals when a workflow fits clearly in one proc.
- When independently meaningful operations must preserve one invariant, collect that state in a named object and pass it explicitly.
- Start with a plain
objectpassed byvar. - Choose
ref objectwhen identity, aliasing, or shared lifetime is part of the design. - Make shared mutation visible in proc parameters and field updates.
Helper placement
- Extract a helper when it names a meaningful step, is reused, isolates a contract, or makes an invariant easier to state.
- To share an implementation across compile-time variants, parameterize one helper with
static[bool]or a static enum and branch withwhen. - Keep a short, one-use sequence in its driver when extraction would only move lines elsewhere.
- Put helpers at module scope when several phases use them or they stand on their own.
- Use a nested proc for logic local to one caller or for an intentional closure.
- A nested proc captures outer locals by default. Mark it
{.nimcall.}when its non-capturing calling convention is required.
Module boundaries
- Give each module one cohesive responsibility and public contract. A module may own several related types or pieces of state.
- Split a module when a part has an independent responsibility, dependency set, lifecycle, or reuse boundary.
- Export only the types and entry points callers need.
- Keep orchestration state and helpers private unless another module is meant to use them.
- Do not use
{.define.}/{.undef.}to scope behavior across modules; use a runtime parameter.
Control flow
- Keep the normal path structured so its invariants remain visible.
- For a closed set of behaviors, represent the kind as data and branch with
case. - Use
methodwhen runtime subtype dispatch is part of the design, rather than as the default way to divide orchestration steps.
Incremental APIs
- When the caller drives consumption piecewise, keep the cursor and lifecycle state in the object's fields so it survives between calls.
- Expose one proc per transition, with
open/close-style lifecycle procs only when a resource or ordering constraint spans calls; keep a one-shot operation a single proc. - Enforce that ordering with an assert on the lifecycle field (for example
assert s.opened) at the start of eachnext-style proc.
Workflow
- Trace the data flow. Identify which values evolve, which steps share them, and which invariants must hold between steps.
- Choose the smallest state scope. Use locals for one clear proc, a plain object for operations preserving one invariant, and a reference only for intentional identity or shared lifetime.
- Shape the helpers. Extract meaningful operations. Keep local incidental logic near its caller.
- Choose module boundaries. Group code by responsibility and contract, then split only at a real dependency, lifecycle, or reuse boundary.
- Define the public surface. Export the minimum caller-facing types and operations.
- Choose dispatch.
Use direct calls and
casefor closed behavior. Introduce runtime dispatch for an open subtype-based design.
State Scope
| Situation | Default shape |
| One linear operation | Local values in one proc |
| Several operations share an invariant | Plain state object passed by var |
| One caller owns a short captured operation | Nested proc |
| Several phases share a named operation | Module-level proc |
| Identity or shared lifetime is required | ref object |
Common Mistakes
| Mistake | Why it is wrong |
| Hiding state shared by several phases in nested captures | The mutation and cross-phase invariants disappear from proc signatures |
| Creating a state type for a short linear calculation | The extra type adds ceremony without clarifying ownership or invariants |
| Extracting every small block into a top-level helper | The reader must jump between names that do not represent meaningful operations |
| Splitting modules by file size alone | File length does not identify a responsibility, dependency, lifecycle, or reuse boundary |
Using a method hierarchy for a closed set of kinds | Static data plus case keeps the possible behaviors visible to the compiler and reader |
| Exporting orchestration helpers or state by default | It turns implementation details into a public compatibility obligation |
Starting with ref object for locally owned state | It introduces aliasing and identity that the workflow does not require |
References
references/orchestration_pattern.md— Inventory reservations across independent operations that share a stock invariant, contrasted with a local calculation.references/parser_state_pattern.md— A scanner object for incremental cursor and lifecycle state.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

