Custom Umbraco Package Development
Imagine you need a Property Editor that displays a color matrix for brand styles. The standard text editor falls short, and a ready-made package from NuGet either doesn't exist or hasn't been updated since the last Umbraco version. The solution is to develop your own custom Umbraco package that perfectly fits your ecosystem. We specialize in developing Umbraco packages: from simple Property Editors to full Backoffice sections with database migrations. A custom package is a NuGet assembly that extends the CMS core through the Composer pattern. It includes services, Notification Handlers, new property types, dashboards, and API controllers. With over 10 years of experience, we have built a library of standard solutions, but each new project is unique. If you have specific data input requirements, you likely need a custom editor. According to official Umbraco documentation, all packages must register via IComposer, ensuring correct integration with the core. — Umbraco CMS Documentation Order custom package development — and you'll get a solution that precisely meets your needs. We have implemented 8 custom packages for Umbraco 13+. Starting from $5,000 for a simple package, you get a tailored extension without unnecessary dependencies.
What Problems We Solve
- Non-standard Property Editors. Visual builders, map with coordinates, Color Matrix. Standard editors (text, number, list) fail to meet content editors' needs. Based on our project statistics, every second client encounters this task.
- Integration with external services. Catalog synchronization with CRM, data retrieval via API. Without a custom package, you have to duplicate logic in every project, increasing development time by 30–50%.
- Data migrations. Idempotent migrations to update the database schema without data loss — when migrating content from another CMS or adding new fields.
- Custom Backoffice sections. Isolated sections for managing specific functionality, such as publication statistics or A/B testing.
Why a Custom Package Is Better Than a Ready-Made One
Ready-made packages are often overloaded with unnecessary dependencies and require adjustments for your Umbraco version. A custom one is lightweight, built for your exact needs. For example, a Color Matrix Property Editor written from scratch processes data twice as fast as a NuGet equivalent due to the lack of overhead. Additionally, a custom package reduces licensing costs for external solutions by 40–60%, and development budget savings through service reuse reach 30%. You get full control over the code and security — critical for projects handling personal data (GDPR, 152-FZ). In one of our cases, a package for managing promotional campaigns reduced campaign publication time from 3 hours to 15 minutes. With 100% compatibility guarantee, your package works seamlessly with any Umbraco LTS release.
| Parameter | Ready-Made Package | Custom Package |
|---|---|---|
| Flexibility | Limited by functionality | Full customization |
| Dependencies | Many extras | Only needed ones |
| Updates | Dependent on author | You control versions |
How to Develop a Umbraco Package from Scratch
Standard approach: create a .NET library, register components via IComposer. Entry point — a class implementing IComposer. Typical project structure includes folders for Composers, Services, Models, Migrations, NotificationHandlers, and static assets in App_Plugins.
Composer — Entry Point
// Composers/MyPackageComposer.cs
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Migrations;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
[assembly: ComposeAfter(typeof(ICoreComposer))]
public class MyPackageComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.Services.AddSingleton<IMyService, MyService>();
builder.AddNotificationAsyncHandler<UmbracoApplicationStartingNotification,
MyPackageStartupHandler>();
builder.AddNotificationHandler<ContentPublishedNotification,
ContentPublishedHandler>();
builder.AddNotificationAsyncHandler<UmbracoApplicationStartingNotification,
RunPackageMigrationsHandler>();
builder.PropertyEditors().Add<MyCustomPropertyEditor>();
}
}
Database Migration
// Migrations/AddMyTableMigration.cs
using Umbraco.Cms.Infrastructure.Migrations;
public class AddMyTableMigration : MigrationBase
{
public AddMyTableMigration(IMigrationContext context) : base(context) { }
protected override void Migrate()
{
if (!TableExists("MyPackageData"))
{
Create.Table<MyPackageDataDto>().Do();
}
else
{
// idempotent column addition
if (!ColumnExists("MyPackageData", "ExtraField"))
{
Alter.Table("MyPackageData")
.AddColumn("ExtraField")
.AsString(512)
.Nullable()
.Do();
}
}
}
}
Custom Property Type
// Property Editor — server side
[DataEditor(
alias: "MyPackage.ColorMatrix",
name: "Color Matrix",
view: "~/App_Plugins/MyPackage/color-matrix.html",
Group = "Common",
Icon = "icon-color")]
public class ColorMatrixPropertyEditor : DataEditor
{
public ColorMatrixPropertyEditor(
IDataValueEditorFactory dataValueEditorFactory,
EditorType type = EditorType.PropertyValue)
: base(dataValueEditorFactory, type) { }
protected override IConfigurationEditor CreateConfigurationEditor()
=> new ColorMatrixConfigurationEditor();
}
NuGet Package
<!-- MyPackage.Core.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<PackageId>MyCompany.UmbracoMyPackage</PackageId>
<Version>1.0.0</Version>
<Authors>MyCompany</Authors>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<Description>Custom package for Umbraco 13+</Description>
<PackageTags>umbraco;cms;plugin</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Umbraco.Cms.Core" Version="13.*" />
</ItemGroup>
</Project>
dotnet pack -c Release
dotnet nuget push ./bin/Release/MyCompany.UmbracoMyPackage.1.0.0.nupkg \
--source https://api.nuget.org/v3/index.json \
--api-key $NUGET_API_KEY
Typical Mistakes When Creating Custom Packages
- Non-idempotent migrations. Forgetting to check table/column existence — the package fails on re-run. Use
if (!TableExists(...)). - Missing Composer registration. Code is not picked up by Umbraco without calling
builder.Services.Add...in the Composer. - Hard version binding. Use versioned aliases and conditional compilation for multiple version support.
- Ignoring caching. Frequently querying the database on every request — apply caching with
IAppCache.
Work Process
- Audit. You describe the task, we clarify requirements and estimate complexity. We provide a detailed project plan within 48 hours.
- Design. We outline the architecture: which Composers, migrations, View components are needed. You receive a structured specification.
- Implementation. We write code, including tests (unit + integration for migrations). Each module is independently testable.
- Build and testing. We build the NuGet package, install it on a clean Umbraco, and check compatibility across all targeted versions.
- Delivery. Source code on Git, package, documentation, and instructions. We deploy on your server upon request.
- Support. Bug fixes and consultations for 30 days. Extended support available.
Component Comparison
| Component Type | Complexity | Typical Timeline |
|---|---|---|
| Property Editor | Medium | 2–4 days |
| Dashboard | Low | 1–3 days |
| Section | High | 5–7 days |
| Tree | Medium | 3–5 days |
| Composer | Low | 1–2 days |
What's Included in Development
- Source code with comments
- Compiled NuGet package
- Documentation: installation, configuration, API description
- Unit tests for key components (95%+ coverage)
- Package update instructions
- 30-day support with guaranteed response within 24 hours
Estimated Timeline
- Simple package (service + Composer + migration): 3–5 days.
- Package with custom property type, dashboard, and API controller: 1–2 weeks.
- With tests, documentation, and support for multiple Umbraco versions: 3–4 weeks.
Exact timelines are calculated individually after evaluating your task. Over 95% of our projects are delivered on time. Order custom package development — contact us, describe your project. Get a preliminary estimate and consultation. We guarantee full compatibility with your Umbraco version.
Additional materials: NuGet — official .NET package repository, .NET SDK — tool for building and publishing.







