Build a component once. Compile it once. Host the same compiled component unchanged in different Snappable-compatible runtimes.
Snappable is a framework that defines a common contract for building applications from independently developed software components. It standardises the connection between a component and the runtime that hosts it, so the component depends on Snappable rather than on one particular application's API or domain-object model.
Different runtimes can offer completely different interfaces, execution models, and data-flow structures while exposing the same Snappable connection. The Component Developer Kit and SnapFusion demonstrate this today: a component developed and tested in the Developer Kit can be loaded and used in SnapFusion without recompilation or source-code changes.
Snappable builds on two other Foldda projects:
- RDA provides the neutral data containers exchanged between components.
- Charian converts a component's own object model to and from RDA through its
IRdainterface — a pattern called self-binding.
- The Problem
- The Breadboard Analogy
- Snappable Advantages: Portability, Composability, and Interchangeability
- Demo: Portable Components Across Runtimes
- Who Snappable Is For
- Get Involved
- License and Commercial Use
Plugin systems make applications extensible, but their components normally belong to one host. A Visual Studio Code extension is built for Visual Studio Code; a Photoshop plugin is built for Photoshop. Each depends on its host's API, lifecycle, and often its domain-object model.
Even when a component's underlying function would be useful elsewhere, moving it to another host normally requires an adapter, source-code changes, or a complete rewrite.
Snappable separates the component from the runtime implementation. A component targets one common Snappable contract, and any compatible runtime implements the corresponding hosting contract. This makes the compiled component host-neutral and runtime-portable within the supported Snappable and platform versions.
Snappable takes its central analogy from a breadboard used to prototype electronic circuits.
A physical breadboard provides standard connection points into which electronic components can be plugged. Different breadboards may wire those points into different circuits, but a compatible component does not have to be rebuilt for each breadboard.
Snappable applies the same separation to software:
| Breadboard concept | Snappable equivalent |
|---|---|
| Electronic component | Independently compiled software component |
| Standard connection point | Snappable component–runtime contract |
| Electrical signal | RDA container |
| Component lead or pin | Charian IRda conversion boundary |
| Wired breadboard | A Snappable-compatible runtime |
| Completed circuit | A component-based application |
The Snappable framework defines the standard connections. A runtime implements a particular wiring arrangement by loading, configuring, connecting, and driving components.
The breadboard does not decide whether an electronic circuit is valid, and Snappable does not decide whether two software components perform compatible functions. Developers still choose appropriate components and design the application circuit.
These terms describe different properties and should not be confused:
| Term | Meaning in Snappable | Provided by Snappable? |
|---|---|---|
| Runtime-portable | The same compiled component can run unchanged in different compatible runtimes | Yes — this is a core purpose |
| Pluggable | A component can connect to a runtime exposing the compatible Snappable contract | Yes |
| Composable | A runtime can connect components into an application data flow | Yes, structurally |
| Data-compatible | Connected components understand compatible meanings and representations | Determined by their data contracts |
| Functionally interchangeable | One component can replace another in the same application role | Only when their functional and data contracts are compatible |
Snappable guarantees a standard route to runtime portability and pluggability. It does not claim that arbitrary components are functionally equivalent.
If two components understand compatible RDA data, they can communicate directly. If their representations differ, the application may require a mapping or transformation component. If two components fulfil the same functional and data contracts, a runtime builder may substitute one for the other without changing unrelated components.
Four elements work together in the Snappable architecture:
- A Snappable component contains a focused capability and owns its internal object model.
- Charian (
IRda) converts between that internal model and a neutral RDA container at the Snappable connection boundary. - The Snappable framework defines the common contract through which the compiled component connects to a runtime.
- A Snappable-compatible runtime implements that contract, controls component lifecycle and execution, and moves RDA containers through its chosen data-flow structure.
For example, Component A may use DataModelX, while Component B uses DataModelY. Neither model has to be compiled into the runtime. Each component performs its own model–RDA conversion, and the runtime carries the resulting RDA containers without adopting or interpreting either model.
Charian's IRda interface provides the model-conversion mechanism:
public interface IRda
{
void FromRda(Rda rda); // reconstruct this object's state from an RDA container
Rda ToRda(); // represent this object's state as an RDA container
}ToRda() converts an object's state into an RDA container. FromRda() reconstructs the object from an incoming container and reports an error when required values cannot be matched. Because the object resolves its own fields at runtime instead of depending on a compiled schema shared with the host, this pattern is called self-binding.
The result is separation on two levels:
- Runtime separation: the component targets Snappable, not one particular runtime implementation.
- Model separation: the runtime transports RDA containers without depending on the component's domain classes.
Snappable is not merely an architectural proposal. Its API, runtime implementations, and components are functional today.
The Component Developer Kit included in this repository is a deliberately simple development and testing runtime. It provides a one-direction pipeline in which developers can build, configure, execute, and test Snappable components.
After compilation, the same component can be loaded and used unchanged in SnapFusion. SnapFusion is a substantially different runtime: it provides a visual, hierarchical environment for composing data-processing applications. The component does not need to be recompiled, rewritten, or adapted to SnapFusion's domain-object model.
This demonstrates Snappable's central technical value in working software: the compiled component depends on the common Snappable contract, not on the runtime in which it was originally developed and tested.
The following demonstration shows an ETL application being assembled from pre-built Snappable components:
The second demonstration shows components being configured individually, collaborating through the runtime, and being swapped when another component fulfils a compatible role:
Snappable serves three related roles: component developers create portable building blocks, application builders compose them into working applications, and runtime developers create the environments that host and connect them. One person or team may take on more than one role.
Build focused software capabilities without tying them to one host application's domain model or proprietary plugin API.
- Reach multiple runtimes: Compile a component once and deploy the same binary unchanged to SnapFusion or another compatible runtime.
- Preserve implementation independence: Keep the component's logic and internal object model separate from runtime-specific classes.
- Simplify development: Build and test in the lightweight Component Developer Kit before using the component in a larger runtime.
- Increase reuse: Maintain one portable component instead of separate integrations for each compatible host.
See Building a Snappable Component for the complete pattern, worked examples, and links to example components in this repository.
Use a Snappable-compatible runtime to combine components into an application that meets a technical or business need. The runtime supplies the wiring; the application builder chooses the parts and designs the circuit.
- Assemble applications faster: Reuse existing components instead of implementing every capability from scratch.
- Build at different scales: Create anything from a single hosted extension to a processing pipeline or a hierarchical SnapFusion application.
- Adapt the circuit: Add mappings where data representations differ, or replace a component when another fulfils compatible functional and data contracts.
- Focus on the outcome: Concentrate on workflow design and validation while the runtime handles hosting, lifecycle, and data transport.
Snappable makes components structurally pluggable; the application builder remains responsible for choosing components that can work together correctly.
See SnapFusion for a ready-to-use runtime to start assembling components into an application, or the demos above for a walkthrough of the process.
Create a specialised environment for hosting and composing portable components while exposing the same standard Snappable connection.
- Reuse portable components: Host compatible compiled components without requiring runtime-specific versions or recompilation.
- Differentiate the runtime: Provide a distinctive user interface, topology, or execution model while retaining component compatibility.
- Avoid domain-model coupling: Exchange RDA containers without adopting or interpreting each component's internal object model.
- Support varied applications: Implement anything from a single embedded component plug to a linear pipeline or visual hierarchy.
See Implementing the Snappable Runtime API for runtime-hosting guidance and the Component Developer Kit reference implementation.
Create focused components and document their input, output, and functional contracts. Each well-defined component expands the set of applications that can be composed from the available parts.
Explore different ways to host and connect the same compiled components: visual designers, embedded pipelines, automated services, specialised tools, or other runtime experiences.
Add component, runtime, lifecycle, failure, and cross-runtime portability tests. Additional end-to-end examples will also make the framework easier to evaluate and adopt.
This project is released under GPL-3.0 for open-source use.
If you want to use it in a proprietary or closed-source product, or distribute it without GPL obligations, a commercial license is available.
Commercial licensing offers:
- Permission for closed-source use
- Legal clarity for enterprises
- Optional support and long-term maintenance
Contact the project owner at contact@foldda.com with questions or enquiries.

