Packaging NiFi extensions as NARs: when teams implement it and why it matters
Teams need NAR packaging as soon as they write custom processors or controller services that must run inside NiFi and survive upgrades. A NAR (NiFi Archive) is the unit NiFi loads: it bundles your compiled classes and resources with its own classloader, and it declares dependencies on other NARs rather than sharing a flat classpath. That isolation is the reason the work exists. Without it, a library your extension ships can collide with a different version NiFi or another extension already uses, and the failure often appears only after a restart or a version change.
The work is needed in three common situations: a new extension that does not exist in the standard bundles, a shared API that several extensions must depend on, and a JDBC or other driver that must load in its own classloader for a specific controller service. Each situation drives different Maven choices, such as whether to use a parent NAR for the shared API, how to mark NiFi-provided dependencies, and which NiFi version the build targets. Confirm the NiFi API version and runtime requirements against the NiFi Developer's Guide and the NiFi download page before you fix the build baseline.
These packaging decisions are hard to undo. Renaming a NAR, changing its dependency layout, or moving a controller service to a new API NAR changes how existing flows reference the component, and a later NiFi 2 upgrade adds its own constraints. Apache NiFi is licensed under Apache-2.0 with no paid edition from the project, so the build, testing, versioning and support work sits with your team or a partner you engage. Decide who owns the Maven parent, the release process for each NAR, and the upgrade test before the first extension ships.
What the NAR mechanism does for NiFi extensions
A NiFi extension ships as a NiFi Archive (NAR), and the NAR is the unit NiFi loads, dependencies included. The cards below cover the pieces of that mechanism that decide how you lay out Maven modules and where classpath conflicts come from.
The NAR as deployable unit
A NAR is a single archive that NiFi unpacks and loads as one extension bundle. You deploy it by copying it into the NiFi extensions directory and restarting or reloading as your version requires. Because the archive is the unit, every processor, controller service and dependency it carries travels together. Check that each NAR contains only what its components need, since everything inside it is visible to that bundle.
NAR dependencies between extensions
One NAR can declare a dependency on another NAR, which lets it reuse that bundle's classes at runtime instead of bundling its own copy. This is how a processor NAR can rely on a controller service API provided elsewhere. Confirm the dependency direction in your POM before you build, because a missing or reversed dependency surfaces as a class-not-found error only when the component is first used.
Parent NAR for shared APIs
A parent NAR carries shared API classes that several extension NARs depend on, so the API is loaded once and its types match across bundles. Without it, each bundle can carry its own copy of the same interface, and a processor may fail to cast a service it was handed. Plan the parent NAR's contents as a stable public contract, because changes to it affect every NAR that depends on it.
Isolated ClassLoader per NAR
Each NAR gets its own ClassLoader, so libraries in one bundle do not replace or leak into another bundle's classes. This isolation prevents many Jackson, Guava or HTTP client version clashes, but it also means that two bundles can hold incompatible copies of the same class. When a component fails with a linkage error, check which NAR loaded the class before changing versions.
Dependency scope and bundled libraries
Maven dependency scope decides what lands inside the NAR archive. Libraries that NiFi already provides should be marked as provided, while libraries only your extension needs should be packaged. Review the packaged dependency tree after each build, because a transitive library pulled in by accident is a common source of conflicts that appear only in a running cluster.
Versioning NARs across upgrades
A NAR is built against a specific NiFi API version, so its compatibility must be checked whenever you upgrade NiFi. Keep the NiFi version as an explicit build property and rebuild every custom NAR as part of the upgrade plan. Confirm the target version's API expectations in the NiFi migration guidance before you assume an existing NAR will load unchanged.
How NiFi isolates ClassLoaders and where conflicts come from
NiFi loads each NAR into its own ClassLoader, and NARs are arranged in a parent and child relationship. A NAR that depends on another NAR sees that NAR's classes through its parent ClassLoader, while everything bundled inside the NAR itself stays in a separate child ClassLoader. Each NAR's own libraries are therefore hidden from every other NAR by default. This isolation is what lets two extensions coexist on the same instance, but it also means that the boundaries you draw in your Maven build determine what each component can see at runtime. Before you package anything, confirm the exact parent and child rules for your NiFi version against the Developer's Guide and the apache/nifi repository, since the mechanics have changed between lines.
Conflicts appear when two NARs each bundle a different version of the same third-party library, such as a JSON parser or HTTP client. Each NAR's classloader can load its own copy without error, but the problem surfaces when objects cross the boundary. A controller service API class loaded from one copy may not be type-compatible with the implementation loaded from another, producing ClassCastException or NoSuchMethodError errors that appear only under certain flows. The same failure happens when an API interface such as a controller service interface is bundled inside more than one NAR. Each copy is a distinct class to the JVM, so a processor cannot cast a service it receives to the interface it expects.
The practical rule is that shared API classes must be loaded once, from a common parent. Put interfaces and any types that cross NAR boundaries in an API NAR that other extensions depend on, and keep implementation details out of it. Before release, list the dependency tree of each NAR and check which libraries it bundles, especially those that also appear in NiFi's own lib directory. Confirm with the NiFi version you run, because the set of libraries provided by the framework is part of what you must match against. Defining this boundary early is far cheaper than discovering a mismatch after a NiFi upgrade.
Packaging decisions: parent NAR, dependency NAR, or bundled libraries
A standalone NAR packages your processor code and every third-party library it needs into one archive. This is the simplest model and fits a single processor or a small set of processors that use libraries NiFi does not already provide, such as a niche parser or a small client SDK. NiFi loads the NAR into its own classloader, so the bundled libraries stay isolated from other extensions. The cost is size and duplication: if five teams each bundle the same JSON or HTTP library, each NAR carries its own copy, and the versions drift apart over time.
- Fits: one or two components, self-contained dependencies, and no shared service interfaces with other NARs.
- Risks: bundled copies of common libraries that conflict with versions NiFi already ships, and larger NARs to patch when a library has a vulnerability.
- Upgrade exposure: the NAR is rebuilt against a specific NiFi version, so you need a rebuild and retest on each NiFi upgrade.
- Avoid bundling: NiFi's own API, Jackson, Jetty or Spring types, which should be marked as provided by the platform.
- Dependency review: list every transitive dependency in the NAR and confirm none duplicates a platform library.
Before release, inspect the NAR contents and confirm that the dependency tree matches what you intended to ship.
A parent NAR holds the shared API and service interfaces that several child NARs need, and child NARs declare it as their parent. NiFi loads the parent once and gives children access to its classes, so common types are not duplicated and a controller service API can be implemented by different providers. This fits organizations that publish several extensions built on a common framework, such as a shared client abstraction used by multiple processors and services. The trade-off is coupling: every child is tied to the parent's API version, and changing a parent interface can break children that were built against the old one.
- Fits: several related NARs that share types and need one authoritative version of them.
- Risks: version lock-in, where a parent change forces every child to rebuild and redeploy at the same time.
- Upgrade exposure: a parent NAR must be deployed in the same NiFi version range as its children, so plan parent and child releases together.
- Keep the parent thin: avoid putting implementation code or heavy libraries in it, because every child inherits them.
- Interface stability: treat published interfaces as contracts and add new methods through new interfaces rather than changing existing ones.
Test that each child loads against the deployed parent, and that a parent upgrade does not silently change behavior in existing flows.
A dependency NAR is the pattern used for controller service APIs. The API NAR defines the interface, an implementation NAR provides it, and processors depend only on the API. This lets a flow swap one implementation for another without changing processor code, and it keeps processors free of the implementation's libraries. It is the approach to use when a shared connection pool, client or cache is consumed by processors that should not know which provider supplies it. The main risk is that the API becomes a long-lived contract, so it should be small and stable.
- Fits: controller services with more than one possible implementation, or processors that consume a service provided elsewhere.
- Risks: a breaking change to the API forces every implementation and consumer to move together.
- Declare the dependency correctly: the consuming NAR must declare the API NAR as a dependency so NiFi resolves the service type at runtime.
- Keep the API free of implementation types: exposing a vendor client class in the interface pushes that library into every consumer.
- Verify service discovery: confirm the processor lists the service in its property descriptor and that validation fails clearly when no provider is installed.
Test the processor against the API alone, using a mock service, and test the implementation separately against the real external system.
JDBC drivers and some vendor SDKs are often incompatible with each other or with NiFi's own libraries, and two flows may need different versions of the same driver at once. Per-instance classloading gives each controller service instance its own classloader, loaded from the driver JAR or NAR that the operator specifies. This fits database connection pools where one NiFi cluster connects to databases that need different driver versions, and where a driver upgrade should not touch other services. The cost is memory, since each loader holds its own copy of the classes, and more operational steps when drivers are added or changed.
- Fits: drivers that must coexist at different versions, or vendor libraries that conflict with platform classes.
- Risks: memory growth from many loader instances, and driver classes leaking across reloads if resources are not released on disable.
- Operational steps: confirm how drivers are supplied to the service in your NiFi version, and whether they must be placed on each node.
- Lifecycle: make sure the service closes connections and releases driver resources in the disable and shutdown hooks.
- Version checks: record which driver version each environment uses, so the flow can be reproduced after an upgrade.
Test connection establishment, disable and re-enable cycles, and a full cluster restart, and watch heap use across repeated cycles.
Implementation sequence for a NAR-based build
This sequence takes an extension from a list of required libraries to a versioned, tested NAR set that loads cleanly in the NiFi version you run in production. Each step produces a written artifact that the next step depends on, so classpath problems surface in development rather than after release.
Inventory libraries and NiFi APIs per extension
The developer who owns each extension lists every third-party library the code imports and every NiFi API it calls, including the nifi-api, nifi-framework-api and any shared service interfaces. For each entry, record whether NiFi already provides it at runtime, whether it must be bundled, and which NiFi version the API belongs to. The output is a short inventory per extension, reviewed by someone who did not write the code. The step is done when every import in the source tree maps to one line in the inventory.
Define the parent NAR and module layout
Decide which code belongs in a parent NAR for shared APIs and which code belongs in each extension NAR, then write the Maven module structure to match. Keep the API and implementation split explicit so that consumers depend on interfaces, not on implementation jars. The output is a multi-module project where each module has a single packaging type and a documented purpose, plus a short note on which modules are published. The step is done when a clean build of the empty skeleton succeeds with the intended parent relationships.
Set dependency scopes and exclusions
Set each dependency to provided where NiFi supplies it, to compile or runtime where the NAR must carry it, and add exclusions for transitive libraries that clash with NiFi's own versions. Pin versions in the parent POM so that every extension in the set resolves the same library versions. The output is a reviewed dependency tree for each module, saved with the build, showing no unintended duplicates of NiFi-provided jars. The step is done when the tree for each module matches the inventory from the first step.
Build and inspect the NAR contents
Run the Maven build and open each generated NAR archive to confirm what it contains. Check that the manifest declares the correct dependency NAR, that bundled jars are the expected versions, and that no NiFi API classes were copied into the extension. Record the checksums of the artifacts so that later builds can be compared against them. The output is an inspection record for each NAR listing its contents and checksum. The step is done when no unexpected jar appears in any archive.
Deploy to a non-production NiFi of the target version
Install the built NARs into a non-production NiFi instance running the exact version that production will use, and confirm the instance uses the same Java runtime as production. Start with a clean node so that no leftover NARs from earlier builds affect the result. Review the NiFi version guidance for the target line before deployment, because the supported runtime and API surface differ between 1.x and 2.x. The output is a running test instance with a logged list of the NARs it loaded. The step is done when the instance starts without errors related to missing or duplicate classes.
Verify component loading and classloading
Confirm in the NiFi interface that each processor, controller service and other component appears under the expected bundle and version, and that shared services resolve to a single instance across extensions. Check the application log for classloader warnings and for any driver loaded twice. Run the component tests against the deployed instance where they apply. The output is a verification record that lists each component, its bundle coordinates and the result of each check. The step is done when every component loads from its intended NAR and no classpath conflict is logged.
Set the versioning and release process
Assign a version to each NAR, record the NiFi version it was built and tested against, and store the inventory, dependency tree, checksums and verification record with the release tag in source control. Define how a future NiFi upgrade triggers a rebuild and a repeat of this sequence, and who approves the release. The output is a release record that lets an operator trace any running NAR back to its source, build and test evidence. Confirm the exact upgrade and compatibility rules with the NiFi migration guidance and the NiFi version you are targeting before the first production release.
Versioning NARs across NiFi upgrades
NARs built for NiFi 1.x must be rebuilt and retested against NiFi 2.x before they go near a production flow. NiFi 1.x cannot be maintained further because it depends on Jetty 9.4, Spring Framework 5.3 and AngularJS 1.8, which cannot be upgraded within that line. The NiFi downloads page states that 1.28 is the last minor release of the version 1 series, so the NARs you maintain should target the 2.x API. Treat the 1.x build as a source of requirements, not as an artifact to carry forward. Before rebuilding, confirm each API class, interface and component your extension uses against the NiFi Migration Guidance, because changes there decide which code compiles unchanged and which needs rework.
The migration path has two required steps. The guidance requires upgrading to NiFi 1.27.0 before moving to 2.0.0, and it changes the flow configuration file from flow.xml.gz to flow.json.gz. Plan the NAR work around that order: confirm that your extensions run on the 1.27.0 intermediate release, then move to 2.x with the new flow file in place. Version each NAR against the NiFi API version it targets, and record that target in the NAR's pom.xml and release notes, so an operator can tell which build belongs on which NiFi line. Keep 1.x and 2.x builds as separate, named releases in your artifact repository so a rollback never requires a rebuild under pressure.
Confirm the upgrade path with your own environment before committing a date. Ask the team that owns each extension whether it depends on any API or component that changed in 2.0, such as the renamed distributed map cache components or the variable registry scope that was replaced by ENVIRONMENT. Run a representative flow on a staging cluster that starts from a copy of the production flow.xml.gz and shows the converted flow.json.gz. Expect the effort to depend on how many extensions you maintain and how far each has drifted from the 2.x API, and make the rebuild and retest of each NAR a tracked item in the upgrade plan.
What drives the effort of a NAR build and how to keep it down
This table lists the factors that change how much work a NiFi extension build takes, how each one moves effort, and what to ask a partner to quote. Read it before requesting a scope, because the first four drivers are usually set by your extension inventory and the last one decides how much regression work repeats with every NiFi release.
| Driver | Why it changes effort | What to ask a partner to quote |
|---|---|---|
| Number of extensions | Each processor, controller service, or reporting task needs its own NAR packaging, API split decisions, and bundle tests. Shared parent NARs reduce repeated work, while unrelated components in one NAR increase rework when one changes. | Quote per extension type, and state whether a shared parent NAR and its API module are included in scope. |
| Third-party libraries with conflicting versions | Libraries that NiFi or other NARs already ship at different versions need dependency analysis, exclusions, or isolation in a separate NAR. Each conflict found late usually means a new build and a new round of runtime testing. | Ask for a dependency inventory step before build estimates, and confirm how version conflicts are reported and resolved. |
| Drivers loaded per instance | JDBC drivers and similar client libraries often need their own classloader so that each service instance can point at a different driver version. This adds packaging decisions, lifecycle checks, and testing across multiple configured instances. | Confirm which drivers are per-instance, which are shared, and how the quote covers testing with more than one configured instance. |
| Number of NiFi versions targeted | Building against both the 1.x and 2.x lines differs in Java runtime, dependency versions, and APIs. Each target version adds a build matrix, a separate test run, and a separate deployment check. | Name the exact NiFi versions in scope and ask whether one codebase with a build profile per version is included. |
| Test coverage in CI | Unit tests with the mock framework are cheap to extend, but integration tests against a running NiFi or a real external system take more setup. Low coverage shifts defect discovery to staging and raises rework cost. | Ask which test layers are included, what the CI pipeline builds and runs on each commit, and who maintains the test fixtures. |
| Packaging and release process | Versioning NARs, signing or checksumming artifacts, and publishing to an internal repository add steps that repeat on every release. A documented process keeps each later release smaller. | Ask whether the quote covers a repeatable release procedure, artifact versioning rules, and handover documentation. |
| Upgrade work for existing NARs | Moving an existing NAR to a newer NiFi line changes dependencies and may require rewriting code that relied on removed or renamed components. Scope grows with the amount of custom code that touches changed APIs. | Ask for an upgrade impact assessment first, and confirm whether the quote covers rework or only rebuilds. |
| Ownership after handover | If the client team will maintain the NARs, the build needs clear documentation, pinned dependency versions, and a test suite the internal team can run. Missing handover material is a common cause of repeat engagements. | Confirm the handover deliverables, the documentation format, and whether knowledge transfer sessions are priced separately. |
Questions teams ask before packaging NiFi extensions
Can our own team build NiFi NARs without outside help?
Yes, a team with Java and Maven experience can build NARs in-house, and many do. The first build is usually the slowest part because the team must learn how NiFi loads extensions, how the NAR Maven packaging works, and how to test against a running NiFi. The harder question is whether the team can keep the build working across NiFi releases and resolve dependency conflicts without disrupting production flows. Ask yourself whether someone on the team will own the extension for its full life, including upgrades, not just the first version.
What skills and tools does a NiFi extension project need?
The work needs four things:
- Java skills at the level needed to write and debug processors, controller services and their tests
- Maven experience to structure parent POMs, NAR dependencies and version management
- A NiFi test environment that matches the production version and Java runtime, which the NiFi administration guide lists as Java 21 minimum for NiFi 2
- Git for version control of the extension source, build configuration and flow definitions
Confirm that your environment can run the target NiFi version before writing code, because the NiFi version decides the API you compile against.
What makes the cost of a NAR project go up?
Cost follows the number of extensions and the number of shared libraries they depend on. Each extension adds build configuration, tests, documentation and a release cycle. Library conflicts add the most unpredictable effort, because two extensions that bundle different versions of the same client library can break each other at runtime, and tracing the cause takes careful analysis of ClassLoader behavior. One-time costs include the initial structure, parent NAR design and test harness. Recurring costs include rebuilding and retesting each extension for every NiFi upgrade. Ask any quote to separate these two categories and to state how many extensions and shared dependencies are in scope.
How long does packaging NiFi extensions usually take?
Duration depends on the same drivers as cost: the number of extensions, how many external libraries they use, how many of those libraries conflict with NiFi's own dependencies, and how complete the test coverage must be. Extensions with no shared dependencies and a clear API design move quickly. Extensions that wrap drivers or SDKs with their own transitive dependencies take longer because the classpath must be isolated and verified. The time to validate a fix on a running NiFi cluster also adds to the schedule when the team does not already have a staging environment. Ask for a schedule that lists these items separately so you can see where the time goes.
How do NARs keep working through NiFi upgrades?
NARs keep working when the extension is built against a stable API and the dependency versions are managed deliberately. Upgrades between NiFi major versions are the highest-risk point. NiFi 2 changed several areas that custom code may touch, and the migration guidance requires upgrading to NiFi 1.27.0 before moving to 2.0.0. Plan for each NAR to be rebuilt, tested and released against every target NiFi version, and keep the parent NAR and dependency versions under version control so that a single change does not silently alter every extension. Confirm with your NiFi version owners which release line you will target and how long you will run both versions in parallel.
What does a fixed-scope NAR engagement cover?
A fixed-scope engagement covers the extensions, deliverables and timelines agreed in writing before work starts. For NAR packaging, a typical written scope lists the number of extensions, the parent NAR structure, the isolation approach for drivers and shared libraries, the test approach, the NiFi versions targeted and the documentation delivered to your team. It should also state what is out of scope, such as operating the NiFi cluster or running extensions in production after handover. DeployOpen does not publish a price list, so a quote follows from this written scope. Ask for the scope in writing before comparing proposals.
Does DeployOpen offer support after the NAR build is delivered?
Ongoing support, upgrades and continuous testing are available as retainers. A retainer can cover rebuilding extensions for new NiFi releases, retesting after dependency updates and handling dependency conflicts that appear in production. Retainers are separate from the fixed-scope build, so the handover should state who owns each extension after delivery. Ask for a written handover that names the artifacts, the build steps, the test suite and the upgrade responsibilities before you decide whether your team or a retainer will carry the work.
How extension NARs connect to the rest of a NiFi platform
A NAR does not stop at the build output. Once it is packaged, it meets the flow registry, the test harness, the CI pipeline, shared controller services and the cluster it runs on. Each of these points can break a deployment that looked correct in isolation, so plan them together.
Flow registry and versioned flows
Flows that use your processors are stored in a flow registry, and a flow saved there records the component types and versions it depends on. If a flow was versioned against one NAR version and the target instance runs another, the import can fail or the flow can reference a component that no longer matches its properties. Decide before release how flows will pin NAR versions and who approves a bundle change. NiFi 2 includes Flow Registry Clients for GitHub and GitLab that store flows in a Git repository. Confirm how each client records bundle versions in the component documentation.
Git-based version control
The NAR source, its POM files and its tests belong in the same repository as the flows that use it, or in a linked repository with a tagged release. Tag each NAR version and keep the version in the POM aligned with what the registry references. Without that link, a rollback of a flow can silently pull a newer processor, or a processor fix can ship without the flow change it requires. Record which NiFi version each NAR was compiled against, since that is the first question during an upgrade.
Testing harness in the build
Unit tests for processors and controller services run against the NiFi test framework in Maven, so they execute during the build before any NAR is deployed. Keep the test dependencies at the same NiFi API version as the target runtime, or tests can pass against classes the instance never loads. Confirm the test harness version for your target release in the developer documentation, and treat a failing test as a blocked release, not a warning.
CI pipeline and artifact promotion
A CI pipeline should build each NAR once, run its tests, and publish the same artifact to every environment. Rebuilding for each stage lets dependency versions drift between dev and production. Add a check that fails when a NAR depends on a NiFi API version other than the one the pipeline targets, and store artifacts in a repository your team controls. Ask your build engineers to confirm where the NiFi Maven dependencies are sourced when the build runs in a restricted network.
Controller services shared across NARs
A processor that uses a controller service depends on the service API NAR, and the service implementation must load in a compatible classloader. If two NARs bundle different copies of the same client library, a processor can receive a service it cannot cast to its expected interface. Map each controller service to the NAR that owns its API, and document which processors consume it. The controller service design should be settled before processors are built on top of it, since changing the API later forces a rebuild of every consumer.
Deployment to clustered NiFi
In a cluster, every node must load the same NAR versions before a flow that uses them is started, or nodes will disagree about the flow and disconnect. Plan a rolling deployment that adds NARs to all nodes first, then imports the flow version that needs them. The NiFi administration guide describes how clusters coordinate through ZooKeeper or Kubernetes state, so confirm the deployment order against that coordination model and test a node restart with the new NAR in place.
What DeployOpen hands over at the end of a NAR packaging engagement
The handover for a NAR packaging engagement is a set of artifacts your team can build, audit and maintain without us. The Maven module layout comes first: one aggregator POM, the extension modules with their nar packaging, the parent NAR that carries the shared NiFi API dependencies, and the NAR dependency declarations between them. Alongside it you receive a dependency report generated from the final build, listing each bundled library, its version, the NAR it sits in, and whether it is provided by the NiFi runtime or packaged with the extension. Which items appear in the report, and in what format, is set out in the written scope before work starts, so the acceptance criteria are known in advance.
The second group covers how the code gets built and changed. You receive the build and test pipeline definition for your CI system, including the steps that run unit tests with the mock framework, produce the NAR artifacts, and fail the build when a dependency falls outside the agreed rules. The versioning and upgrade runbook describes how NAR versions map to the NiFi release line you run, which parent NAR version to pick for a given NiFi upgrade, and the order in which clusters are updated. Ask whether the runbook covers the 1.x to 2.x migration path and the flow file and component changes that come with it, since those affect which extension versions can run side by side during a rollout.
The third item is training for the internal team. We walk your engineers through the module layout, the rules for adding a dependency, how to read the dependency report, and how to run the upgrade steps against a non-production cluster. Ask for the training notes in writing and for a named owner on your side who will maintain the rules after the engagement closes. Plan for these items to be reviewed on your own build, not only on ours, because a handover that has never been run by your team tends to fail at the first dependency change.
How DeployOpen scopes and delivers NiFi extension packaging
DeployOpen approaches NAR packaging as an engineering task with written boundaries: which extension points are needed, how the Maven module layout separates shared APIs from implementations, and how the build is verified against the NiFi version your team runs. Work is delivered inside your infrastructure and source control, with the decisions recorded for your own engineers.
How we scope
- Inventory the custom components, their dependencies and the NiFi versions they must run on
- Agree which shared APIs go into parent NARs and which libraries stay inside each extension
- Identify drivers, SDKs and other classes that need per-instance classloading or version isolation
- Record scope, deliverables and timelines in writing before the build starts, since most engagements are fixed-scope
How we build
- Structure Maven modules into API, implementation and NAR packaging layers with explicit dependency declarations
- Check the resulting NAR classloader graph for duplicate or conflicting libraries before any deployment
- Test extensions against the NiFi version in use, including upgrade runs on a copy of your flows
- Keep the build reproducible in your source control so artifacts can be rebuilt from a tagged commit
How we hand over
- Document the module layout, parent NAR contract, versioning rules and the reasons behind each dependency choice
- Provide runbooks for deploying, rolling back and replacing NAR files on a running NiFi cluster
- Walk your engineers through the build and classloading decisions so the team can maintain the packaging
- Deliver test results and known limitations in the handover package, with open items listed clearly
How we support
- Review NAR changes when you move to a new NiFi release, including checks against the NiFi migration guidance
- Plan upgrades of extensions alongside the NiFi platform, so dependency versions move together
- Offer ongoing support, upgrades and continuous testing as a retainer for teams that want continued coverage
- Confirm with your NiFi version and environment which support scope fits your change process

