NEXSS FLOW · INTEGRATIONS
8 min read | Updated 2026-10-01
Integrations

Bundles and Extensions

How Flow's microkernel design works: core.Bundle is the contract through which bundles contribute actions, modifiers, directives, and operators. Default convention, multi-bundle variants, and local loose packages.

extensionsbundles@requiremicrokernel

The microkernel model

Nexss Flow uses a microkernel-style design: core.Bundle is the contract through which bundles contribute action libraries and compiler extensions. The CLI assembles its built-in bundles, while @require can load a bundle for a flow.

A package's presence under extensions/ alone does not enable it. The CLI must assemble the bundle at startup, or a flow must @require it. This keeps the runtime surface explicit: nothing is silently loaded.

go go
const ID = "loop"

func init() {
    core.Register(ID, Bundle)
}

func Bundle(opts map[string]string) core.Bundle {
    return core.Bundle{
        ID:        ID,
        Libraries: []action.Library{{Name: ID}},
        Primaries: []core.PrimaryExtension{loopKeyword{}},
        Fixtures:  fixturesFS,  // optional embed.FS
    }
}

ID is a short label ("loop", "sandbox", "fs") — never an import path. It survives forks, module moves, and vendor directories. Two extensions with the same ID panic at init().

Resolution rules for @require

Four resolution paths cover remote modules, explicit subpackages, local paths with go.mod, and local loose packages without go.mod.

  • **Remote module root** — @require github.com/org/repo automatically appends /nexssflow by convention.
  • **Explicit subpackage** — @require github.com/org/repo/nexssflow_dev is preserved as-is. Flow does not append /nexssflow.
  • **Local path with go.mod** — @require ./sub/dir walks upward for go.work or go.mod. If found, resolves natively as a subpackage.
  • **Local loose package (zero config)** — @require ./localtest with no ancestor go.mod is auto-vendored into the temporary execution harness as an internal subpackage. **Zero go.mod files are written to the user workspace.**
  • **Missing bundle** — if no bundle is found, Flow halts with an actionable error directing the developer to scaffold it with nflow init --bundle.

Multi-bundle variants

A single repository can provide multiple bundle flavors (dev mocks, production backends, specialized profiles) by naming explicit directories.

bash bash
my-project/
├── nexssflow/          # Default profile
│   └── library.go
├── nexssflow_dev/      # Development mock profile
│   └── library.go
└── nexssflow_prod/     # Production hardened profile
    └── library.go
nflow nflow
# Uses the custom variant directly without appending /nexssflow
@require github.com/nexssp/my-project/nexssflow_dev

Scaffolding extensions with nflow init

To quickly generate an extension bundle inside any existing repository, use nflow init.

bash bash
# Scaffolds ./nexssflow/library.go in the current directory
nflow init --bundle

# Scaffolds a custom variant ./nexssflow_dev/library.go
nflow init --bundle nexssflow_dev

# Scaffolds a complete starter Flow project in ./my-pipeline
nflow init my-pipeline

External repositories (any language)

Flow is language-agnostic. Any repository (Python, Node.js, Rust, C++, or Go) can expose capabilities to Nexss Flow by adding an extension bundle directory.

The shim can be a thin wrapper over external.ExecAction, a sandbox engine, or a direct Go import if the repo is already in Go. This is the path to wire existing business actions directly into AI agent tools, HTTP routers, and orchestration graphs.

Fixtures vs SelfTest

Prefer nflows/*.nflow fixtures over inline SelfTest(). A fixture is a real .nflow file the runner executes like any pipeline — it grows with the DSL, with no Go code to change when the feature evolves.

nflow nflow
@description "Loop loop(...) until(...)"
@assert: result.n == 3

{ n: 0 } -> loop( { n: .n + 1 } ) until( .n >= 3 )

Use inline SelfTest() only when the feature cannot be expressed in pure DSL: temporary files needed outside the workspace (Files: map), subprocesses requiring mocked systems (exec, http.request), or runtime-only middleware without observable state assertions (:cache=, :retry=).