DoubleSync.Core 17.0.1-alpha.0.16

DoubleSync for Umbraco

Sync schema, content, media, and people between Umbraco environments — directly from the backoffice. DoubleSync is an Umbraco v17+ backoffice package with a merge editor, SyncPacks, RBAC, audit trail, and more.

Free Community tier includes schema sync and diff preview. Pro and Agency tiers unlock full content, media, and people sync with conflict resolution.


Table of Contents


Features

Feature Community Pro Agency
Schema sync (data types + document types) Yes Yes Yes
Content sync (documents with variants) Yes Yes
Media sync (folders + binary blobs) Yes Yes
People sync (users, groups, members) Yes Yes
Diff / status preview Yes Yes Yes
Merge editor (per-property conflict resolution) Yes Yes
SyncPack (portable ZIP packages) Yes Yes
Culture-specific sync Yes Yes
Node-level push/pull with dependency resolution Yes Yes
RBAC (per-user-group, per-environment) Yes Yes
Audit trail with user attribution Yes Yes
Restore points (auto-archive before sync) Yes Yes
Delete detection Yes Yes
Scheduled auto-snapshots Yes
Azure Blob Storage transport Yes
Unlimited domains Yes

Requirements

  • .NET 10 (or later)
  • Umbraco v17+
  • An API User on each remote Umbraco instance (see Quick Start)

Installation

dotnet add package DoubleSync.Umbraco

For Azure Blob Storage support (Agency license):

dotnet add package DoubleSync.Storage.Azure

Restart Umbraco. The DoubleSync section appears in the backoffice.


Quick Start

1. Create an API User

On every remote Umbraco instance you want to sync with, create an API User:

Option A — Via appsettings.json (recommended for automation):

{
  "Umbraco": {
    "CMS": {
      "Security": {
        "BackOfficeApiClients": {
          "doublesync": {
            "ClientId": "umbraco-back-office-doublesync",
            "ClientSecret": "your-secret-here",
            "AllowedGrantTypes": ["client_credentials"],
            "AllowedScopes": ["All"]
          }
        }
      }
    }
  }
}

Option B — Via the Umbraco Backoffice:

  1. Go to Settings → Users → API Users.
  2. Click Create API User.
  3. Name it (e.g. doublesync). The Client ID will be umbraco-back-office-doublesync.
  4. Copy the Client Secret shown.
  5. Assign Content and Settings section permissions.

2. Install & Initialise the CLI

dotnet tool install --global DoubleSync.Cli --add-source https://nuget.double.pt/nuget
doublesync init

This creates a .doublesync/ directory with configuration and snapshot storage.

3. Configure Environments

# Configure source (e.g. DEV)
doublesync config set-source \
  --url https://dev.example.com \
  --client-id umbraco-back-office-doublesync \
  --client-secret your-dev-secret

# Configure target (e.g. UAT)
doublesync config set-target \
  --url https://uat.example.com \
  --client-id umbraco-back-office-doublesync \
  --client-secret your-uat-secret

# Verify
doublesync config show

4. Sync!

# Pull everything from DEV
doublesync pull --include-content --include-media

# Preview what would change on UAT
doublesync push --dry-run

# Push to UAT
doublesync push --include-content --include-media

# Check differences
doublesync status

Umbraco Backoffice Dashboard

When the DoubleSync.Umbraco NuGet package is installed, a DoubleSync dashboard appears in the Content section with two tabs:

Sync Tab

  • Add Environment — Register remote Umbraco instances with name, URL, Client ID, and Client Secret.
  • 🔌 Test — Verify connectivity and authentication.
  • ⬇ Pull — Export from the remote instance and import into this one.
  • ⬆ Push — Export from this instance and import into the remote one.
  • 📊 Status — Compare and show a diff summary without applying changes.
  • 🗑 Delete — Remove a configured environment.
  • Sync Options — Toggle whether to include Content and/or Media (schema is always synced).
  • Last Result — Summary of the most recent sync operation with counts and error details.
  • Sync History — Table of the last 10 sync operations with timestamps and results.

Documentation Tab

Built-in reference documentation covering:

  • Getting started guide
  • Dashboard action reference
  • Sync option descriptions
  • CLI usage examples
  • Filtering & conflict resolution flags
  • API User setup instructions
  • Architecture overview
  • Troubleshooting tips

CLI Command Reference

Initialisation & Configuration

doublesync init                          # Create .doublesync/ config directory
doublesync config set-source --url ... --client-id ... --client-secret ...
doublesync config set-target --url ... --client-id ... --client-secret ...
doublesync config show                   # Display current configuration
doublesync test-connection --url ... --client-id ... --client-secret ...

Schema Sync

# Export all schema (data types + document types)
doublesync schema-export

# Export only data types or document types
doublesync schema-export --type datatypes
doublesync schema-export --type doctypes

# Import schema (with optional dry-run)
doublesync schema-import
doublesync schema-import --dry-run

# Compare schema between snapshot and target
doublesync schema-diff

Content Sync

# Export all content
doublesync content-export

# Export a specific branch or culture
doublesync content-export --path /home
doublesync content-export --culture en-US

# Import content (with optional dry-run)
doublesync content-import
doublesync content-import --dry-run

# Compare content
doublesync content-diff

Media Sync

doublesync media-export
doublesync media-import
doublesync media-import --dry-run
doublesync media-diff

Bidirectional Sync (Push / Pull)

# Pull from remote → local snapshot → import here
doublesync pull
doublesync pull --include-content --include-media

# Push from here → export → import to remote
doublesync push
doublesync push --include-content --include-media
doublesync push --schema-only

# Preview changes
doublesync push --dry-run
doublesync pull --dry-run

# Check what changed since last sync
doublesync status

Filtering Options

Flag Example Description
--type --type datatype Filter by item type: datatype, doctype, content, media
--path --path "/Home/About" Filter by content tree path
--culture --culture en-US Filter by culture (variant content)
--dry-run schema-import --dry-run Preview changes without applying
--interactive push --interactive Prompt before each change
--strategy push --strategy source-wins Conflict resolution strategy

Conflict Resolution

When items have been modified on both source and target since the last sync:

Strategy Behaviour
source-wins Source version overwrites target
target-wins Target version is kept, source changes discarded
skip Conflicting items are skipped entirely
doublesync push --strategy source-wins
doublesync push --strategy target-wins
doublesync push --strategy skip
doublesync push --interactive   # Choose per-item

Architecture

Project Structure

DoubleSync/
├── src/
│   ├── DoubleSync.Core/           # Core library
│   │   ├── ApiClient/             #   Umbraco Management API HTTP client + OAuth2
│   │   ├── Config/                #   Configuration management
│   │   ├── Diff/                  #   Diff engine (schema, content, media)
│   │   ├── Export/                #   Exporters (schema, content, media)
│   │   ├── Import/                #   Importers (schema, content, media)
│   │   ├── Models/                #   API + snapshot data models
│   │   ├── Snapshot/              #   JSON snapshot reader / writer
│   │   └── Sync/                  #   Bidirectional orchestrator + manifest
│   ├── DoubleSync.Cli/            # CLI tool (System.CommandLine)
│   │   └── Program.cs             #   All CLI commands and argument parsing
│   └── DoubleSync.Umbraco/        # Umbraco backoffice package (Razor Class Library)
│       ├── Client/                #   Frontend (Lit + TypeScript + Vite)
│       │   ├── src/
│       │   │   ├── api/           #     API client for backend endpoints
│       │   │   ├── dashboard/     #     Dashboard Lit web component
│       │   │   └── index.ts       #     Entry point
│       │   ├── public/
│       │   │   └── umbraco-package.json  # Extension manifest
│       │   ├── package.json
│       │   ├── vite.config.ts
│       │   └── tsconfig.json
│       ├── Composers/             #   Umbraco startup composer (Swagger config)
│       ├── Controllers/           #   Management API controller
│       ├── Services/              #   Backend sync service
│       └── wwwroot/               #   Built frontend assets
├── tests/
│   ├── DoubleSync.Core.Tests/     # 91+ unit tests (xUnit)
│   └── DoubleSync.Integration.Tests/  # Integration tests against live instances
├── demo-instances/
│   ├── dev/                       # DEV Umbraco instance (port 44311)
│   └── uat/                       # UAT Umbraco instance (port 44312)
├── start-demo.ps1                 # Script to launch both demo instances
└── DoubleSync.sln

NuGet Packages

Package Type Description
DoubleSync.Core Class Library API client, exporters, importers, diff engine, sync orchestrator
DoubleSync.Umbraco Razor Class Library Umbraco backoffice package with Lit web components
DoubleSync.Storage.Azure Class Library Azure Blob Storage provider for snapshots and media

Published to NuGet.org.

How It Works

  1. Export — Reads data types, document types, content, and media from an Umbraco instance via the Management API. Saves as human-readable JSON snapshots.
  2. Diff — Compares snapshots against a target instance. Uses GUID-first matching with name/alias fallback.
  3. Import — Creates/updates items on the target in dependency order (folders → data types → element types → document types → content → media).
  4. Sync Manifest — Tracks the last sync state to detect conflicts on subsequent operations.
  5. Publish State — Captures and restores per-culture publish state for content documents.

Developer Guide

Internal references (team)

  • Test environments matrix — every demo / QA host on OVH, which tier it runs, DB names, license setup, bring-up commands.
  • NuGet publishing — private vs public feed, queue-time toggle for nuget.org pushes, obfuscation, source protection.
  • Licensing policy — Ed25519 signing, domain binding, LTS-to-LTS upgrade model, renewal flow.
  • Multi-developer workflow — concurrency primitives (per-env lock, staleness watermark, dirty-bit pull guard).
  • Project status — current sprint, open work.

Prerequisites

Building

# Build everything
dotnet build

# Build release
dotnet build -c Release

Running Tests

# Run all unit tests (91+ tests)
dotnet test

# Run with verbose output
dotnet test --verbosity normal

# Run specific test project
dotnet test tests/DoubleSync.Core.Tests/DoubleSync.Core.Tests.csproj

Demo Instances

Two Umbraco test instances are included for development and testing:

# Launch both with the helper script
powershell -ExecutionPolicy Bypass -File start-demo.ps1

# Or start individually
dotnet run --project demo-instances/dev/DemoUmbraco.Dev.csproj
dotnet run --project demo-instances/uat/DemoUmbraco.Uat.csproj
Instance URL Login Password
DEV https://localhost:44311/umbraco admin@demo-dev.test DoubleSync1234!
UAT https://localhost:44312/umbraco admin@demo-uat.test DoubleSync1234!

API Credentials (auto-seeded):

Instance Client ID Client Secret
DEV umbraco-back-office-doublesync-dev doublesync-dev-secret
UAT umbraco-back-office-doublesync-uat doublesync-uat-secret

Start script options:

# Full build (frontend + backend + launch)
powershell -ExecutionPolicy Bypass -File start-demo.ps1

# Skip frontend build
powershell -ExecutionPolicy Bypass -File start-demo.ps1 -NoFrontend

# Skip backend build
powershell -ExecutionPolicy Bypass -File start-demo.ps1 -NoBuild

# Skip both builds
powershell -ExecutionPolicy Bypass -File start-demo.ps1 -NoBuild -NoFrontend

Frontend Development

The Umbraco backoffice frontend uses Lit web components with TypeScript and Vite:

cd src/DoubleSync.Umbraco/Client

# Install dependencies
npm install

# Build for production (output to wwwroot/App_Plugins/DoubleSync/)
npm run build

# Watch mode (rebuild on changes)
npm run dev

Key files:

File Purpose
src/dashboard/doublesync-dashboard.element.ts Main dashboard component
src/api/doublesync-api.ts TypeScript API client
src/index.ts Entry point (imports dashboard)
public/umbraco-package.json Umbraco extension manifest
vite.config.ts Build configuration

Umbraco UI components used: uui-tab-group, uui-tab, uui-box, uui-table, uui-button, uui-tag, uui-toggle, uui-loader-bar.

Packing & Publishing NuGet

# Pack all projects
dotnet pack src/DoubleSync.Core/DoubleSync.Core.csproj -c Release
dotnet pack src/DoubleSync.Cli/DoubleSync.Cli.csproj -c Release
dotnet pack src/DoubleSync.Umbraco/DoubleSync.Umbraco.csproj -c Release

# Publish to private feed
dotnet nuget push src/DoubleSync.Core/bin/Release/DoubleSync.Core.{VERSION}.nupkg \
  --source https://nuget.double.pt/nuget --api-key YOUR_KEY

dotnet nuget push src/DoubleSync.Cli/bin/Release/DoubleSync.Cli.{VERSION}.nupkg \
  --source https://nuget.double.pt/nuget --api-key YOUR_KEY

dotnet nuget push src/DoubleSync.Umbraco/bin/Release/DoubleSync.Umbraco.{VERSION}.nupkg \
  --source https://nuget.double.pt/nuget --api-key YOUR_KEY

Version Bumping

Update the <Version> element in all three .csproj files:

  • src/DoubleSync.Core/DoubleSync.Core.csproj
  • src/DoubleSync.Cli/DoubleSync.Cli.csproj
  • src/DoubleSync.Umbraco/DoubleSync.Umbraco.csproj

Troubleshooting

Problem Solution
Connection refused / timeout Ensure the remote instance is running and accessible. Check firewalls, HTTPS certs, and that the URL is correct.
401 Unauthorized Client ID or Client Secret is wrong, or the API User was deleted. Re-check credentials.
403 Forbidden API User lacks section permissions. Grant Content and Settings access.
Schema import: "parent not found" Folder was deleted on target. Run a full schema sync to re-create the folder hierarchy.
Content import: "document type not found" Schema must be synced first. Pull/Push handles this automatically; for manual commands, run schema-import before content-import.
Dashboard shows 404 Ensure DoubleSync.Umbraco NuGet package is installed and the app has been restarted. The API runs at /umbraco/management/api/v1.0/doublesync/.
Frontend console errors Clear browser cache and reload. Ensure the built JS is in wwwroot/App_Plugins/DoubleSync/.
Conflicts detected Use --strategy source-wins, --strategy target-wins, or --interactive to resolve.

License

DoubleSync is a commercial package with a free Community tier. See LICENSE.md for the full license agreement.

  • Community (Free) — Schema sync and diff preview on up to 2 environments
  • Pro — Full content, media, and people sync with merge editor
  • Perpetual — Pro features with a one-time purchase for a specific Umbraco version
  • Agency — Unlimited domains, Azure Blob Storage, scheduled snapshots, priority support

For pricing details, visit doublesync.io/pricing.

Copyright (c) 2026 Double Digital, Lda.

Showing the top 20 packages that depend on DoubleSync.Core.

Packages Downloads
DoubleSync.Storage.Azure
Azure Blob Storage provider for DoubleSync. Stores snapshots, media blobs, and SyncPacks in Azure Blob Storage. Requires DoubleSync.Umbraco Agency license.
0

.NET 10.0

  • No dependencies.

Version Downloads Last updated
17.0.1-alpha.0.25 0 02/09/2026
17.0.1-alpha.0.22 0 02/09/2026
17.0.1-alpha.0.21 0 02/09/2026
17.0.1-alpha.0.20 0 02/09/2026
17.0.1-alpha.0.19 0 02/09/2026
17.0.1-alpha.0.18 0 02/09/2026
17.0.1-alpha.0.16 0 02/09/2026
17.0.1-alpha.0.15 0 02/09/2026
17.0.1-alpha.0.14 0 02/09/2026
17.0.1-alpha.0.13 0 02/09/2026
17.0.1-alpha.0.12 0 02/09/2026
17.0.1-alpha.0.11 0 02/09/2026
17.0.1-alpha.0.10 0 02/09/2026
17.0.1-alpha.0.9 0 02/09/2026
17.0.1-alpha.0.8 0 02/09/2026
17.0.1-alpha.0.7 0 02/09/2026
17.0.1-alpha.0.6 0 02/09/2026
17.0.1-alpha.0.5 0 02/09/2026
17.0.1-alpha.0.4 0 02/09/2026
17.0.1-alpha.0.3 0 02/09/2026
17.0.0 0 02/09/2026
17.0.0-alpha.0 0 02/09/2026
1.0.0 0 02/09/2026
0.4.0 0 02/09/2026
0.3.0 0 02/09/2026
0.2.0 0 02/09/2026
0.1.0 0 02/09/2026