# How Plausible Differentiates Community Edition (CE) from Enterprise Edition (EE) Builds

> Discover how Plausible Analytics differentiates Community Edition (CE) from Enterprise Edition (EE) builds. Learn about compile-time flags, config files, and license validation.

- Repository: [Plausible Analytics/analytics](https://github.com/plausible/analytics)
- Tags: internals
- Published: 2026-05-19

---

**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`](https://github.com/plausible/analytics/blob/main/lib/plausible.ex), where the module defines a strict list of environments that constitute CE builds.

```elixir

# 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.

```elixir
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`](https://github.com/plausible/analytics/blob/main/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`](https://github.com/plausible/analytics/blob/main/config/prod.exs) and [`config/dev.exs`](https://github.com/plausible/analytics/blob/main/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`](https://github.com/plausible/analytics/blob/main/lib/plausible/billing/enterprise_plan.ex), represents contractual enterprise agreements.

```elixir

# 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`](https://github.com/plausible/analytics/blob/main/extra/lib/license.ex) defines `Plausible.License.ensure_valid_license/0`, which the application calls during startup.

```elixir

# 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`](https://github.com/plausible/analytics/blob/main/lib/plausible_web/components/billing/billing.ex) inspects the plan type to render different pricing tables and feature lists.

```elixir

# 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`](https://github.com/plausible/analytics/blob/main/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_builds` list and `always/1` macro in [`lib/plausible.ex`](https://github.com/plausible/analytics/blob/main/lib/plausible.ex) strip EE modules from CE binaries during compilation.
- **Configuration isolation**: [`config/ce.exs`](https://github.com/plausible/analytics/blob/main/config/ce.exs) provides CE-specific settings, while EE builds use production configuration files with enterprise features enabled.
- **Schema differentiation**: The `Plausible.Billing.EnterprisePlan` schema only exists in EE builds, acting as a runtime feature flag.
- **License validation**: `Plausible.License.ensure_valid_license/0` enforces EE compliance at startup, compiled out entirely for CE.
- **UI and logic branching**: Components in [`lib/plausible_web/components/billing/billing.ex`](https://github.com/plausible/analytics/blob/main/lib/plausible_web/components/billing/billing.ex) and [`lib/plausible/teams/billing.ex`](https://github.com/plausible/analytics/blob/main/lib/plausible/teams/billing.ex) check 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`](https://github.com/plausible/analytics/blob/main/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`](https://github.com/plausible/analytics/blob/main/lib/plausible/application.ex), which calls `Plausible.License.ensure_valid_license/0` defined in [`extra/lib/license.ex`](https://github.com/plausible/analytics/blob/main/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.