AcornDB 0.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package AcornDB --version 0.1.0
                    
NuGet\Install-Package AcornDB -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AcornDB" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AcornDB" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="AcornDB" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AcornDB --version 0.1.0
                    
#r "nuget: AcornDB, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AcornDB@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AcornDB&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=AcornDB&version=0.1.0
                    
Install as a Cake Tool

🌰 AcornDB

AcornDB logo

AcornDB is a lightweight, reactive, embedded database for .NET β€” for devs who’d rather ship products than pay $400/month to store 5MB of JSON.

🐿️ Nutty by design. Practical by necessity.


πŸš€ Why AcornDB Exists

Most apps don’t need Cosmos DB, Kafka, or Redis.

They need:

  • Fast, local-first persistence
  • Simple per-tenant or per-user storage
  • Offline support + syncing that doesn’t make you cry

AcornDB is for:

  • Desktop apps
  • IoT devices
  • Mobile backends
  • CLI tools
  • Serverless & edge workloads
  • And yes β€” you with the single-user SaaS that stores 10KB per user

🍁 Core Concepts

Term What It Means
Tree<T> A local document collection β€” your "embedded table"
NutShell<T> An object wrapped with metadata (TTL, version, timestamp)
ITrunk<T> Storage abstraction: File, Memory, Azure Blob, or versioned
Branch A connection to a remote Tree via HTTP
Tangle A live sync session between two Trees
Grove A set of Trees managed + synced together
Canopy (Internal) sync orchestrator living inside the Grove
Stash/Crack/Toss Insert, read, and delete objects β€” squirrel-style verbs
Shake() Manual sync trigger

πŸ”§ Features

Feature Description
🌰 Stash, Crack, Toss Drop-in persistence with zero boilerplate
πŸ›‘οΈ NutShell<T> Versioned, timestamped, TTL-wrapped records
πŸ” Branch, Tangle, Grove Live sync between Trees, across machines
πŸͺ’ Entangle<T>() Automatically starts syncing on stash/toss
🎩 Oversee<T>() One-liner to monitor remote branches
βš–οΈ Squabble() + Judge Built-in conflict resolution with custom override
🧠 INutment<TKey> Typed ID interface for strongly keyed documents
🧹 SmushNow() Manual compaction of log-based storage
πŸ›°οΈ ExportChanges() / ImportChanges() Manual sync if you’re old-school
🌲 Grove.Plant<T>() Auto-creates and registers a Tree<T>
πŸ” Totem-based auth (coming) Because why not woodland-themed security?

πŸ§ͺ Getting Started

# Coming soon to NuGet:
dotnet add package AcornDB
// Create a Tree and stash some data
var tree = new Tree<User>();
tree.Stash("abc", new User { Name = "Squirrelius Maximus" });

// Set up syncing with a Grove
var grove = new Grove();
grove.Plant(tree);
grove.Oversee<User>(new Branch("http://localhost:5000")); // auto-sync!

tree.Shake(); // optionally force a sync

πŸ—„οΈ Storage Abstraction (Trunks)

AcornDB uses Trunks to abstract storage β€” swap your backend without touching your Tree code.

Available Trunks

Trunk Use Case History Sync
FileTrunk<T> Simple file-based storage ❌ βœ…
MemoryTrunk<T> Fast in-memory (great for tests) ❌ βœ…
DocumentStoreTrunk<T> Full versioning & time-travel βœ… βœ…
AzureTrunk<T> Azure Blob Storage ❌ βœ…

Examples

// πŸ“ FileTrunk: Simple, no history
var fileTree = new Tree<User>(new FileTrunk<User>("data/users"));
fileTree.Stash("alice", new User("Alice"));

// πŸ’Ύ MemoryTrunk: Fast, non-durable
var memTree = new Tree<User>(new MemoryTrunk<User>());
memTree.Stash("bob", new User("Bob"));

// πŸ“š DocumentStoreTrunk: Full history & versioning
var docTree = new Tree<User>(new DocumentStoreTrunk<User>("data/versioned"));
docTree.Stash("charlie", new User("Charlie v1"));
docTree.Stash("charlie", new User("Charlie v2"));

var history = docTree.GetHistory("charlie"); // Get previous versions!
// Returns: 1 previous version ("Charlie v1")

// πŸ”„ Export/Import between trunks
var sourceTrunk = new FileTrunk<User>("data/source");
var targetTrunk = new AzureTrunk<User>("connection-string");

targetTrunk.ImportChanges(sourceTrunk.ExportChanges()); // Migrate!

Time-Travel with DocumentStoreTrunk

var trunk = new DocumentStoreTrunk<Product>("data/products");
var tree = new Tree<Product>(trunk);

tree.Stash("widget", new Product("Widget v1.0"));
tree.Stash("widget", new Product("Widget v2.0"));
tree.Stash("widget", new Product("Widget v3.0"));

var current = tree.Crack("widget");     // "Widget v3.0"
var history = tree.GetHistory("widget"); // ["Widget v1.0", "Widget v2.0"]

// All changes stored in append-only log: data/products/changes.log

NotSupportedException Pattern

Trunks that don't support history throw NotSupportedException:

var memTree = new Tree<User>(new MemoryTrunk<User>());
try {
    var history = memTree.GetHistory("user1");
} catch (NotSupportedException) {
    Console.WriteLine("MemoryTrunk doesn't support history!");
}

Feature Detection with ITrunkCapabilities

Check trunk features without exceptions:

var trunk = new MemoryTrunk<User>();
var caps = trunk.GetCapabilities();

Console.WriteLine($"Trunk: {caps.TrunkType}");
Console.WriteLine($"History: {caps.SupportsHistory}");
Console.WriteLine($"Sync: {caps.SupportsSync}");
Console.WriteLine($"Durable: {caps.IsDurable}");
Console.WriteLine($"Async: {caps.SupportsAsync}");

// Use extension methods for quick checks
if (trunk.CanGetHistory())
{
    var history = trunk.GetHistory("user1");
}
else
{
    Console.WriteLine("This trunk doesn't support history");
}

Capability Matrix:

Trunk History Sync Durable Async
FileTrunk ❌ βœ… βœ… ❌
MemoryTrunk ❌ βœ… ❌ ❌
DocumentStoreTrunk βœ… βœ… βœ… ❌
AzureTrunk ❌ βœ… βœ… βœ…

🌐 Sync with TreeBark

TreeBark is the HTTP sync server for AcornDB - it exposes Trees over REST endpoints.

Quick Start Sync Server

// Server side (AcornSyncServer project)
var grove = new Grove();
grove.Plant(new Tree<User>(new FileTrunk<User>("data/users")));
grove.Plant(new Tree<Product>(new FileTrunk<Product>("data/products")));

// Run with: dotnet run --project AcornSyncServer
// TreeBark starts on http://localhost:5000

TreeBark REST API

Endpoint Method Description
/ GET Health check + API docs
/bark/{treeName}/stash POST Stash a nut to remote tree
/bark/{treeName}/crack/{id} GET Crack a nut from remote tree
/bark/{treeName}/toss/{id} DELETE Toss a nut from remote tree
/bark/{treeName}/export GET Export all nuts from tree
/bark/{treeName}/import POST Import nuts into tree

Client-Side Sync with Branch

// Client side - connect to remote TreeBark server
var localTree = new Tree<User>(new MemoryTrunk<User>());
var branch = new Branch("http://localhost:5000/bark/User");

// Manual push
localTree.Stash("alice", new User("Alice"));
branch.TryPush("alice", localTree.Crack("alice"));

// Manual pull
await branch.ShakeAsync(localTree); // Pulls all remote changes

// Auto-sync with Tangle
var grove = new Grove();
grove.Plant(localTree);
grove.Entangle<User>(branch, "sync-session-1"); // Auto-syncs on every stash!

Full Sync Example

Server (dotnet run --project AcornSyncServer):

var grove = new Grove();
grove.Plant(new Tree<User>(new DocumentStoreTrunk<User>("data/users")));
// TreeBark running on http://localhost:5000

Client 1 (Desktop App):

var tree1 = new Tree<User>(new FileTrunk<User>("client1/users"));
var branch = new Branch("http://localhost:5000");

tree1.Stash("alice", new User("Alice"));
branch.TryPush("alice", tree1.Crack("alice")); // Syncs to server

Client 2 (Mobile App):

var tree2 = new Tree<User>(new MemoryTrunk<User>());
var branch = new Branch("http://localhost:5000");

await branch.ShakeAsync(tree2); // Pulls "alice" from server!
var alice = tree2.Crack("alice"); // "Alice" is now local

🌰 AcornDB Visualizer - Web UI

Explore your Grove with an interactive web dashboard!

cd AcornVisualizer
dotnet run
# Open browser to http://localhost:5100

Features:

  • πŸ“Š Live Dashboard - Real-time stats on trees, nuts, and operations
  • 🌳 Tree Explorer - Browse all trees with detailed metadata
  • πŸ“ˆ Graph View - Interactive circular node visualization
  • πŸ” Nut Inspector - View payloads, timestamps, and history
  • βš™οΈ Trunk Info - See capabilities (history, sync, durable, async)
  • πŸ”„ Auto-Refresh - Updates every 5 seconds

Perfect for:

  • Local development and debugging
  • Visual demos and presentations
  • Understanding your grove structure
  • Monitoring nut operations

See AcornVisualizer/README.md for full documentation.


🌲 P2P File System Sync (Same Host)

For same-host multi-process scenarios, AcornDB supports file system-based peer-to-peer sync without needing a server!

How It Works

Instead of HTTP, processes sync via a shared directory:

Process 1 (data/process1) ──┐
                            β”œβ”€β”€β–Ί Sync Hub (data/sync-hub)
Process 2 (data/process2) β”€β”€β”˜

Each process:

  • Maintains its own local DocumentStoreTrunk
  • Exports changes to the shared sync hub
  • Imports changes from other processes
  • Resolves conflicts via timestamp comparison

Example: Two Processes on Same Host

Process 1:

var localTree = new Tree<User>(new DocumentStoreTrunk<User>("data/process1/users"));
var syncHub = new FileSystemSyncHub<User>("data/sync-hub");

localTree.Stash("alice", new User { Name = "Alice" });

// Export to hub
syncHub.PublishChanges("process1", localTree.ExportChanges());

Process 2:

var localTree = new Tree<User>(new DocumentStoreTrunk<User>("data/process2/users"));
var syncHub = new FileSystemSyncHub<User>("data/sync-hub");

// Import from hub
var changes = syncHub.PullChanges("process2");
foreach (var shell in changes)
{
    localTree.Stash(shell.Id, shell.Payload);
}

// Process 2 now has Alice!

Try the Demo

# Terminal 1
cd SyncDemo
run-demo.cmd 1

# Terminal 2
cd SyncDemo
run-demo.cmd 2

Watch changes sync between processes in real-time via the file system!

When to Use File-Based vs HTTP Sync

Scenario Recommended Approach
Same host, multiple processes 🟒 File-based P2P
Different hosts 🟒 TreeBark HTTP
Desktop apps with multiple instances 🟒 File-based P2P
Mobile to cloud 🟒 TreeBark HTTP
Distributed systems 🟒 TreeBark HTTP
CLI tools 🟒 File-based P2P

🧱 Project Structure

Folder Purpose
AcornDB Core engine (Tree, NutShell, Trunk, Tangle)
AcornSyncServer TreeBark: HTTP sync server (REST API)
AcornVisualizer Web UI: Interactive grove dashboard
AcornDB.Canopy SignalR hub + visualizations
AcornDB.Demo Examples showcasing all features
SyncDemo Live multi-client sync demonstration
AcornDB.Test xUnit tests (26 passing)

πŸ§™ What's Coming

  • πŸ” Auth: Totems, ForageRights, Critters, and BarkCodes
  • πŸ“‘ Mesh sync: Peer-to-peer Tangle networks
  • πŸ“¦ NuGet & CLI: Install and create projects with acorn new
  • πŸ” AutoRecovery: Offline-first sync queue with resilience
  • πŸ§ͺ Playgrounds: Sample apps, code snippets, and demos
  • 🎨 Visualizer Enhancements: Real-time updates, diff viewer, dark mode


🌲 The Acorn Ethos

🐿️ Serious software. Zero seriousness.

AcornDB was born out of frustration with bloated infra, soulless APIs, and naming things like DataClientServiceManagerFactoryFactory.

So we built something better β€” not just in function, but in vibe.

We believe:

  • Developers deserve fun.
  • Tools should make you smile, not sigh.
  • Syncing JSON should not require Kubernetes and a degree in wizardry.
  • "Toss the nut and shake the tree" should be valid engineering advice.

If you’ve ever rage-quit YAML, yelled at Terraform, or cried syncing offline-first apps β€”
welcome. You’ve found your grove.

🌰 Stash boldly. Crack with confidence. And never, ever apologize for getting a little squirrelly.

🦦 Built with acorns and sarcasm

We’re tired of YAML. Tired of cloud bills. Tired of DataServiceFactoryClientFactoryFactory.

So we built AcornDB.

If you fork this, star it, or build something fun β€” send us your weirdest squirrel pun.


🐿️ Stay nutty.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on AcornDB:

Package Downloads
AcornDB.Canopy

🌲 AcornDB.Canopy - SignalR hub and real-time visualization extensions for AcornDB. Adds Hardwood HTTP server, live sync orchestration, and real-time grove monitoring capabilities.

AcornDB.Persistence.Cloud

🌰 Cloud storage providers for AcornDB - AWS S3, Azure Blob Storage, and other cloud-based trunk implementations. Separate package to keep core AcornDB lean.

AcornDB.Persistence.RDBMS

🌰 RDBMS storage providers for AcornDB - SQLite, SQL Server, PostgreSQL, MySQL trunk implementations for relational database persistence.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.0 184 10/7/2025
0.3.0 160 10/7/2025
0.1.0 176 10/6/2025

Initial release with core features: Tree, NutShell, Trunk abstraction, file/memory/document storage, and sync capabilities.