How Plausible Differentiates Community Edition (CE) from Enterprise Edition (EE) Builds
Plausible Analytics relies on compile-time Mix environment flags, conditional configuration files, and runtime license validation to produce distinct Community Edition (CE) and Enterprise Edition (EE) artifacts from a single Elixir codebase.
Plausible Analytics is an open-source web analytics platform that maintains both a free Community Edition and a commercial Enterprise Edition within the same repository. Understanding how the plausible/analytics codebase differentiates between these editions reveals a sophisticated build-time conditional compilation strategy that strips proprietary features from the open-source release while avoiding code duplication.
Compile-Time Environment Flags
The primary mechanism for distinguishing editions lives in lib/plausible.ex, where the module defines a strict list of environments that constitute CE builds.
# In lib/plausible.ex
@ce_builds [:ce, :ce_test, :ce_dev]
This module attribute @ce_builds acts as the source of truth throughout the codebase. When developers compile the application with MIX_ENV=ce (or ce_test, ce_dev), the build system treats the artifact as a Community Edition release.
The always/1 Macro for Conditional Compilation
Plausible leverages a macro generated by Plausible.Extra to guard code paths. The always/1 macro evaluates whether the current Mix.env() appears in the @ce_builds list, allowing the compiler to include or exclude entire modules based on the target edition.
require Plausible.Extra
# This code block only exists in CE builds
if Plausible.Extra.always(Mix.env() in [:ce, :ce_test, :ce_dev]) do
# CE-specific implementations
end
Conversely, EE-exclusive code uses the inverse check, ensuring that proprietary features never compile into CE binaries.
Separate Configuration Files
Plausible ships distinct configuration files for each edition. The file config/ce.exs contains settings specific to Community Edition builds, such as disabled license requirements and limited feature toggles.
Standard EE builds rely on config/prod.exs and config/dev.exs, which load enterprise-specific dependencies and feature flags. The router also checks Mix.env() against CE environments to conditionally mount routes that are exclusive to Enterprise Edition, ensuring that administrative and billing endpoints remain inaccessible in CE deployments.
Enterprise-Only Schemas and Modules
Enterprise Edition introduces database schemas that do not exist in CE builds. The Plausible.Billing.EnterprisePlan schema, defined in lib/plausible/billing/enterprise_plan.ex, represents contractual enterprise agreements.
# In lib/plausible/billing/enterprise_plan.ex
defmodule Plausible.Billing.EnterprisePlan do
use Ecto.Schema
schema "enterprise_plans" do
field :monthly_pageview_limit, :integer
field :hourly_api_request_limit, :integer
field :site_limit, :integer
timestamps()
end
end
Because this file resides outside the CE compile-time guards, it only exists in EE bytecode. The presence of this schema serves as a runtime discriminator; business logic queries the association to determine whether enterprise features should activate.
Runtime License Enforcement
While CE builds ship without license checks, EE builds include a mandatory validation step. The module extra/lib/license.ex defines Plausible.License.ensure_valid_license/0, which the application calls during startup.
# In lib/plausible/application.ex
defmodule Plausible.Application do
use Application
def start(_type, _args) do
# EE-only code path
unless Mix.env() in [:ce, :ce_test, :ce_dev] do
Plausible.License.ensure_valid_license!()
end
Supervisor.start_link(children(), opts())
end
end
If the license key is missing or invalid, the function raises an error, halting the boot process. This check is compiled out of CE builds entirely, allowing the Community Edition to run without any license configuration.
Feature Gating in UI and Business Logic
The differentiation extends to the web interface and domain logic. The billing component in lib/plausible_web/components/billing/billing.ex inspects the plan type to render different pricing tables and feature lists.
# In lib/plausible_web/components/billing/billing.ex
def render_plan_features(plan) do
case plan do
%Plausible.Billing.EnterprisePlan{} ->
render_enterprise_features(plan)
_ ->
render_standard_features(plan)
end
end
Similarly, lib/plausible/teams/billing.ex contains logic that grants unlimited sites and higher API rate limits only when an EnterprisePlan association exists. This pattern ensures that EE entitlements remain dormant in CE deployments, even if someone manually inserts enterprise data into the database.
Environment-Specific Testing
The test suites also respect the edition boundary. Files containing :ce_test in their name run exclusively against CE builds, while EE-specific tests execute under the standard :test environment. This separation prevents accidental compilation of enterprise test logic into Community Edition releases and ensures that CI pipelines for the open-source repository do not fail due to missing proprietary dependencies.
Summary
- Compile-time guards: The
@ce_buildslist andalways/1macro inlib/plausible.exstrip EE modules from CE binaries during compilation. - Configuration isolation:
config/ce.exsprovides CE-specific settings, while EE builds use production configuration files with enterprise features enabled. - Schema differentiation: The
Plausible.Billing.EnterprisePlanschema only exists in EE builds, acting as a runtime feature flag. - License validation:
Plausible.License.ensure_valid_license/0enforces EE compliance at startup, compiled out entirely for CE. - UI and logic branching: Components in
lib/plausible_web/components/billing/billing.exandlib/plausible/teams/billing.excheck for enterprise plan associations to toggle functionality.
Frequently Asked Questions
What Mix environments are considered Community Edition builds?
Plausible defines three CE environments in lib/plausible.ex: :ce for production builds, :ce_dev for development, and :ce_test for testing. Any Mix.env() value outside this list triggers an Enterprise Edition compilation path.
How does Plausible prevent EE code from compiling into CE binaries?
The codebase uses the always/1 macro from Plausible.Extra to wrap EE-specific modules and function calls. When MIX_ENV is set to :ce, :ce_test, or :ce_dev, the compiler evaluates these guards as false and excludes the protected code from the resulting bytecode.
Where does the license check occur in Plausible EE?
The license validation happens at application startup in lib/plausible/application.ex, which calls Plausible.License.ensure_valid_license/0 defined in extra/lib/license.ex. This check runs only in Enterprise Edition builds; CE deployments lack this code path entirely.
Can Community Edition users upgrade to EE without recompiling?
No. Because Plausible relies on compile-time conditional compilation to remove EE features from CE binaries, upgrading requires recompiling the application with MIX_ENV=prod (or another EE environment) and providing a valid license key. The CE binary cannot dynamically enable enterprise features at runtime.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →