Skip to content

Bundles

Granit ships 135 packages. That level of granularity is great for control, but overwhelming when you just want to start a new project. You should not have to know the full module graph to get a working API up.

Bundles solve this. A bundle is a meta-package that pulls in a curated set of related modules. One package reference, one Add*() call, and the entire group is wired.

BundleIncludesUse case
EssentialsCore, Timing, Guids, Validation, ExceptionHandling, ObservabilityEvery project
ApiEssentials + ApiVersioning, ApiDocumentation, Cors, Idempotency, CookiesREST API projects
DocumentsTemplating.Scriban, DocumentGeneration.Pdf, DocumentGeneration.ExcelDocument generation
NotificationsNotifications + Email.Smtp, Sms, Push, SignalRMulti-channel notifications
SaaSApi + MultiTenancy, Settings, Features, Localization, BackgroundJobs, Caching.HybridFull SaaS platform

Each bundle is a NuGet meta-package with no code of its own. It only declares dependencies on the modules it groups.

Reference the bundle package and call the corresponding method on the Granit builder:

builder.AddGranit<AppModule>(granit => granit
.AddSaaS());

Bundles are built on the same GranitBuilder fluent API that individual modules use. If a bundle groups more than you need, skip it and pick modules directly:

builder.AddGranit<AppModule>(granit => granit
.AddEssentials()
.AddModule<GranitTemplatingScribanModule>()
.AddModule<GranitDocumentGenerationPdfModule>());

This gives you full control without losing the ergonomics of the builder pattern.

You can combine any number of bundles in a single call. Deduplication is automatic: the module dependency graph tracks what is already registered and skips duplicates. Calling .AddSaaS() (which includes Api, which includes Essentials) and then .AddNotifications() works without conflict.

// SaaS already includes Api and Essentials — no duplicates
builder.AddGranit<AppModule>(granit => granit
.AddSaaS()
.AddNotifications()
.AddDocuments());

Bundles are convenience, not requirement. If your project only needs two or three specific packages, reference them directly:

<PackageReference Include="Granit.Core" />
<PackageReference Include="Granit.Observability" />
<PackageReference Include="Granit.ExceptionHandling" />

This keeps your dependency footprint minimal and avoids pulling in modules you will never configure.