Feature Flags Guide

Table of Contents


Overview

Reinhardt employs a highly granular feature flag system with 70+ features across 3 levels of granularity:

  1. Bundle Features: minimal, standard, full
  2. Feature Groups: database, auth, cache, middleware
  3. Individual Features: jwt, redis-backend, cors

Benefits

  • Reduced Compile Time: Exclude unnecessary features
  • Smaller Binary Size: Only include used code
  • Minimized Dependencies: Only required crates included
  • Flexible Configuration: From microservices to full-stack apps

Basic Usage

Default (full) ⚠️ Changed in v0.1.0-alpha.2

[dependencies]
reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web" }  # Enables full bundle (all features)

Note: The default has changed from standard to full. See Migration Guide for details.

Standard Configuration

For a balanced setup without all features:

[dependencies]
reinhardt = {
	version = "0.1.0-alpha.18",
	package = "reinhardt-web",
	default-features = false,
	features = ["standard"]
}

Custom Configuration

[dependencies]
reinhardt = {
	version = "0.1.0-alpha.18",
	package = "reinhardt-web",
	default-features = false,
	features = ["minimal", "database", "db-postgres", "auth-jwt"]
}

Bundle Features

minimal ⚠️ Changed in v0.1.0-alpha.2

Lightweight bundle with essential features for microservices and simple APIs.

Includes:

  • Core (types, macros, HTTP)
  • Dependency Injection
  • HTTP Server
  • URL routing (always included)
reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", default-features = false, features = ["minimal"] }

Binary: ~5-10 MB | Compile: Very fast


standard

Balanced configuration for most projects. ⚠️ PostgreSQL is now included by default.

Includes:

  • minimal features
  • Database (ORM, migrations, PostgreSQL backend)
  • REST API (Serializers, ViewSets, Parsers, Renderers)
  • Auth, Middleware, Sessions
  • Pagination, Filtering, Throttling, Versioning
  • Templates, Signals
reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", default-features = false, features = ["standard"] }

Binary: ~20-30 MB | Compile: Medium

Note: db-postgres is now explicitly included. For other databases, use db-mysql or db-sqlite.


full (default) ⚠️ Now the default

All features enabled (batteries-included).

Includes: standard + admin, graphql, websockets, cache, i18n, mail, sessions, static-files, storage

reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web" }  # default enables full
# Or explicitly:
reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", features = ["full"] }

Binary: ~50+ MB | Compile: Slow

Note: The full feature now recursively enables all -full features in sub-crates, ensuring comprehensive activation of all functionality.

Feature Inheritance Note: Bundle features use inheritance (full includes standard, which includes minimal). This means features like database and auth may appear in multiple bundles' definitions in Cargo.toml. This is intentional and ensures each bundle works independently without requiring lower-level bundles. Cargo handles duplicate feature activations efficiently.


Recursive -full Feature Structure

Reinhardt implements a recursive feature flag system where each crate level provides its own full or {module}-full feature that aggregates all features from that crate and its sub-crates.

Three-Level Architecture:

  1. Sub-Crate Level: Individual full features

    • Example: reinhardt-orm/full, reinhardt-sessions/full
    • Aggregates all features within that specific sub-crate
  2. Parent Crate Level: Module-specific {module}-full features

    • Example: reinhardt-db/database-full, reinhardt-core/core-full, reinhardt-rest/rest-full
    • Aggregates all module features + all sub-crate full features
  3. Root Crate Level: Top-level full feature

    • Aggregates all parent {module}-full + all standalone crate full features
    • Provides complete framework activation

Example Activation Chain:

# Root level
reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", features = ["full"] }
# ↓ enables
# reinhardt-db/database-full
# ↓ enables
# reinhardt-orm/full, reinhardt-migrations/full, etc.

Parent Crate -full Features:

Parent CrateFull FeatureIncludes
reinhardt-dbdatabase-fullAll 8 database sub-crates with their full features
reinhardt-corecore-fullAll 11 core sub-crates with their full features
reinhardt-restrest-fullAll 9 REST sub-crates with their full features
reinhardt-pagespages-fullSSR, renderers, and component sub-crates with their full features
reinhardt-urlsurls-fullAll 3 URL routing sub-crates with their full features
reinhardt-viewsviews-fullViewSets sub-crate with full feature
reinhardt-authauth-fullSessions sub-crate + all auth features
reinhardt-didi-fullParams sub-crate + DI features
reinhardt-utilsutils-fullAll 4 utility sub-crates with their full features
reinhardt-adminadmin-fullPanel sub-crate with full feature
reinhardt-serverserver-fullServer sub-crate with full feature

Direct Usage of Module-Specific Features:

You can directly use module-specific -full features for fine-grained control:

# Enable only database functionality with all sub-features
reinhardt-db = { version = "0.1.0-alpha.18", features = ["database-full"] }

# Enable only REST API functionality with all sub-features
reinhardt-rest = { version = "0.1.0-alpha.18", features = ["rest-full"] }

# Combine multiple module-full features
reinhardt = {
    version = "0.1.0-alpha.18",
    package = "reinhardt-web",
    default-features = false,
    features = [
        "minimal",
        "reinhardt-db/database-full",
        "reinhardt-rest/rest-full"
    ]
}

Benefits:

  • Comprehensive Activation: One full feature activates everything at that level and below
  • Modular Control: Use {module}-full for specific functional domains
  • Predictable Behavior: Clear hierarchy prevents missing features
  • Easy Testing: Quickly enable all features for a module during development

Preset Bundles

BundlePurposeKey Features
api-onlyREST API onlySerializers, ViewSets, Auth, Pagination
graphql-serverGraphQL APIGraphQL, Auth, Database
websocket-serverReal-timeWebSockets, Auth, Cache
cli-toolsCLI/Background jobsDatabase, Migrations, Tasks, Mail
test-utilsTestingTest utilities, Database

Feature Categories

Database

database

Enables general database functionality.

features = ["database"]  # Includes: ORM, migrations, contenttypes

Database-Specific

FeatureDatabaseNotes
db-postgresPostgreSQLDefault
db-mysqlMySQL-
db-sqliteSQLiteLightweight
db-cockroachdbCockroachDBUses Postgres protocol

Authentication

FeatureMethodAuto-enables
authFoundation-
auth-jwtJWTauth
auth-sessionSessionauth, sessions
auth-oauthOAuthauth
auth-tokenTokenauth

Cache

FeatureBackendExposure
redis-backendRedisRoot-level
redis-clusterRedis ClusterSubcrate only*
redis-sentinelRedis SentinelSubcrate only*
memcached-backendMemcachedSubcrate only*

Workaround for subcrate-only features:

reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", features = ["cache"] }
reinhardt-cache = { version = "0.1.0-alpha.18", features = ["redis-cluster"] }

API

FeatureFormatDefault
apiBasic API-
serialize-jsonJSON✅ (via serializers)
serialize-xmlXML-
serialize-yamlYAML-

Middleware

FeatureFunctionality
middlewareFoundation (auto-enables sessions)
middleware-corsCORS
middleware-compressiongzip/brotli
middleware-securitySecurity headers
middleware-rate-limitRate limiting

Dependency Injection

FeatureDescriptionAuto-enables
diFull DI systemreinhardt-di/params, reinhardt-core/di

The di feature enables FastAPI-style dependency injection with parameter extraction:

use reinhardt::prelude::*;
use reinhardt::{post, Body, Cookie, Header, Json, Path, Query};

#[post("/handler/{id}/", name = "handler")]
async fn handler(
    Path(id): Path<i64>,
    Query(params): Query<SearchParams>,
    Json(body): Json<CreateRequest>,
) -> ViewResult<Response> {
    // ...
}

Note: The minimal and standard bundles automatically include the di feature, so parameter types (Body, Cookie, Header, Json, Path, Query) are available without explicit configuration.


Other Features

FeatureDescriptionKey Crates
adminAdmin panelreinhardt-admin, reinhardt-forms, reinhardt-pages
pagesWASM-based frontend with SSRreinhardt-pages
graphqlGraphQL APIreinhardt-graphql
websocketsReal-timereinhardt-websockets
i18nInternationalizationreinhardt-i18n
mailEmail sendingreinhardt-mail
sessionsSession mgmtreinhardt-auth (includes sessions subcrate)
static-filesStatic servingreinhardt-utils/staticfiles
storageStorage abstractionreinhardt-utils/storage
tasksBackground jobsreinhardt-tasks
shortcutsDjango-style helpersreinhardt-shortcuts
pluginPlugin systemreinhardt-dentdelion

Plugin System

FeatureDescriptionKey Features
pluginPlugin system foundationStatic plugin registration, plugin registry
plugin-wasmWASM plugin supportDynamic plugin loading, wasmtime integration
plugin-cliCLI integrationcrates.io integration, plugin management commands

The plugin system allows extending Reinhardt applications through static and dynamic plugins:

# Static plugins only
reinhardt-dentdelion = { version = "0.1", default-features = false }

# With WASM support
reinhardt-dentdelion = { version = "0.1", features = ["wasm"] }

# Full plugin system (static + WASM + CLI)
reinhardt-dentdelion = { version = "0.1", features = ["full"] }

See reinhardt plugin commands for managing plugins.


reinhardt-pages

WASM-based reactive frontend framework with server-side rendering (SSR) support.

Usage with reinhardt-admin-cli:

# Create a pages-based project
reinhardt-admin startproject myapp --with-pages

# Create a pages-based app
reinhardt-admin startapp myfeature --with-pages

Architecture:

  • 3-layer structure: client/ (WASM UI), server/ (server functions), shared/ (common types)
  • WASM frontend: Runs in browser using wasm-bindgen
  • Server-side rendering (SSR): Pre-render pages on server
  • Client-side hydration: Interactive after initial load
  • Type-safe server functions: RPC-style communication with #[server_fn] macro

Key Features:

  • Reactive UI components
  • Conditional compilation (cfg(target_arch = "wasm32"))
  • Single-server architecture (API + static files from same server)
  • Bootstrap UI integration
  • History API routing
  • Global state management
  • SPA mode with index.html fallback

Configuration Example:

[dependencies]
reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", features = ["admin"] }

[lib]
crate-type = ["cdylib", "rlib"]  # cdylib for WASM, rlib for server

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = ["Window", "Document", "Element"] }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { version = "1", features = ["full"] }

Development Workflow:

# Install WASM build tools (first time only)
cargo make install-wasm-tools

# Build WASM and start development server
cargo make dev

# Or watch mode with auto-rebuild
cargo make dev-watch

# Production build
cargo make dev-release

RunServer Options for WASM Projects:

# Start server with WASM frontend
cargo run --bin manage runserver --with-pages

# Custom static directory
cargo run --bin manage runserver --with-pages --static-dir build

# Disable SPA mode (no index.html fallback)
cargo run --bin manage runserver --with-pages --no-spa

See examples/examples-twitter for a complete implementation.


Task Backends

The tasks feature provides background job processing with multiple backend options:

FeatureBackendPersistenceScalabilityUse Case
tasksImmediate/DummyNo-Development/Testing
tasks-redisRedisYesHighProduction (caching)
tasks-rabbitmqRabbitMQYesVery HighProduction (messaging)
tasks-sqliteSQLiteYesLowSmall-scale production

Configuration Example:

# Redis backend
reinhardt-tasks = { version = "0.1", features = ["redis-backend"] }

# RabbitMQ backend (recommended for production)
reinhardt-tasks = { version = "0.1", features = ["rabbitmq-backend"] }

# SQLite backend
reinhardt-tasks = { version = "0.1", features = ["database-backend"] }

See Task Backends Documentation for detailed comparison.


Major Crate Features

CrateDefault FeaturesKey Features
reinhardt-diNoneparams, dev-tools, generator
reinhardt-dbbackends, pool, postgres, orm, migrationssqlite, mysql, contenttypes
reinhardt-authNonejwt, session, oauth, token, argon2-hasher
reinhardt-restserializers, parsers, rendererspagination, filters, throttling, versioning
reinhardt-cacheNoneredis-backend, redis-cluster, memcached-backend
reinhardt-middlewareNonecors, compression, security, rate-limit
reinhardt-sessionsNonedatabase, file, cookie, jwt
reinhardt-testNonetestcontainers, static, websockets
reinhardt-dentdelionNonewasm, cli, full
reinhardt-tasksNoneredis-backend, rabbitmq-backend, database-backend
reinhardt-panelNonetemplates, file-uploads, full

Auto-enabled dependencies:

  • di feature → reinhardt-di/params (parameter extraction types)
  • poolreinhardt-di (database connection injection)
  • minimal / standarddi (DI system included in bundles)

Usage Scenarios

Use CaseConfigurationBinary
Microservicedefault-features = false, features = ["minimal"]~5-10 MB
REST APIfeatures = ["api-only", "db-postgres", "auth-jwt"]~20-25 MB
GraphQL/WebSocketfeatures = ["graphql", "websockets", "db-postgres"]~30-35 MB
Full-Featuredfeatures = ["full"]~50+ MB
CLI/Backgroundfeatures = ["cli-tools"]~15-20 MB

Best Practices

Disable default-features: Use default-features = false for explicit control

Explicit Database: Specify database backend (e.g., db-postgres, db-sqlite)

Environment-Specific: Use feature profiles (dev, prod)

Test Configuration: Add test-utils in [dev-dependencies] only


Troubleshooting

Common Issues

"feature not found": Check Quick Reference for correct feature names

Linker Errors: Install database client libraries (e.g., libpq-dev for PostgreSQL)

Runtime "feature not enabled": Add required feature to Cargo.toml

Debugging: Use cargo tree -e features | grep reinhardt to check enabled features


Migration Guide

Breaking Changes in v0.1.0-alpha.2

1. Default Feature Changed: standardfull

Before (v0.1.0-alpha.1):

reinhardt = { version = "0.1.0-alpha.1", package = "reinhardt-web" }  # Enabled: standard bundle

Now (v0.1.0-alpha.2):

reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web" }  # Enables: full bundle (all features)

Impact:

  • ⚠️ Longer compile time: Full bundle includes all features (admin, graphql, websockets, etc.)
  • ⚠️ Larger binary size: ~50+ MB (was ~20-30 MB with standard)
  • More features available: All Reinhardt features are immediately usable

To keep previous behavior:

reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", default-features = false, features = ["standard"] }

2. minimal Feature Now Includes Core Functionality

Before (v0.1.0-alpha.1):

# minimal was empty - no features enabled
features = ["minimal"]

Now (v0.1.0-alpha.2):

features = ["minimal"]

Impact:

  • More useful: minimal now provides a working microservice framework
  • Backward compatible: Adding features is non-breaking

Equivalent to:

  • Routing, DI, params, server, core

3. standard Now Includes PostgreSQL by Default

Before (v0.1.0-alpha.1):

features = ["standard"]  # Database support, but no specific backend

Now (v0.1.0-alpha.2):

features = ["standard"]  # Includes db-postgres explicitly

Impact:

  • Works out of the box: Database features now work without additional configuration
  • ⚠️ PostgreSQL dependency: libpq-dev (or equivalent) required at build time

For other databases:

# MySQL
reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", default-features = false, features = ["standard", "db-mysql"] }

# SQLite
reinhardt = { version = "0.1.0-alpha.18", package = "reinhardt-web", default-features = false, features = ["standard", "db-sqlite"] }

4. Removed Features

The following features have been removed (they had no effect):

  • serialize-json
  • serialize-xml
  • serialize-yaml

Reason: All three features enabled the same dependencies (reinhardt-rest/serializers), providing no actual format-specific control.

Impact:

  • ⚠️ Build may fail if you explicitly used these features
  • No functional impact: Serialization still works via reinhardt-rest/serializers

Migration:

# Before
features = ["serialize-json", "serialize-xml"]

# After
features = ["reinhardt-rest", "reinhardt-rest/serializers"]
# Or simply use "rest" or "standard" bundle

Migration Checklist

  • Update Cargo.toml if you want to keep standard instead of full
  • Install PostgreSQL development libraries if using standard or full
  • Remove serialize-* features if explicitly specified
  • Test build with new configuration
  • Update documentation references

Summary

Reinhardt provides 70+ features with 3 granularity levels (bundle, group, individual).

Default: full bundle (all features) ⚠️ Changed from standard

Key bundles: minimal (microservice), standard (balanced), full (all features, default), api-only, graphql-server, cli-tools

Auto-enabled dependencies: direinhardt-di/params, poolreinhardt-di, middlewaresessions, auth-sessionsessions

Best Practice: Use default-features = false for explicit control


  • Bundle Features: See Bundle Features section above
  • Feature Categories: See Feature Categories section above
  • Usage Scenarios: See Usage Scenarios section above
  • Project Overview - Repository and README
  • Getting Started Guide - Getting started guide