Framework
sulu/sulu avatar
sulu/sulu

sulu/sulu: the Symfony core behind a multi-language content management system

Core framework that implements the functionality of the Sulu content management system

1,363 stars372 forksPHPMIT

At a glance

What is it?
The core framework of Sulu, an open source PHP CMS built on Symfony, developed for multi-lingual and multi-portal sites with an extensible administration interface. It is the dependency every Sulu project pulls in, and the two maintained release lines, 3.0 and 2.6, were both published on the same day.
Who is it for?
sulu/sulu suits a Symfony team that needs a CMS with first-class translation and multiple portal support, and that wants to extend it with bundles rather than patches. It does not suit a team that wants a lightweight content layer for a handful of pages, because this is the core of a full CMS with an admin interface, a media manager and a content workflow.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • sulu/sulu1,363 ★ · +3
Star history
Repository2026-10-172026-11-07
sulu/sulu1.4k1.4k

3 Stars in the last 21 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

What the repository is, and what it is not

Sulu is a highly extensible open source PHP content management system based on the Symfony framework, developed to deliver robust multi-lingual and multi-portal websites while providing an intuitive and extensible administration interface to manage the full content lifecycle.

This repository holds the core framework of that system. The README is explicit about the consequence: the framework implements the functionality that is built into the CMS and is therefore a dependency of all Sulu projects.

So there are three distinct things in the ecosystem and it is worth keeping them apart. There is the core framework, which is this repository. There is the skeleton, a pre-configured project template at `sulu/skeleton` that the README points to if you want to start a new Sulu project. And there is the set of official Sulu bundles in the Sulu GitHub organisation, which is where you go if you are extending an existing project.

That division is a sensible answer to the problem of a CMS that is both a framework and a product. The core stays a library that composes bundles, the skeleton stays a starting point, and a project decides which bundles it wants.

The primary language in the metadata is PHP, the licence is MIT with a `LICENSE` file at the root, and the repository is not archived with the last push on 2026-10-16. The default branch is `3.0`, and the homepage is sulu.io.

Two release lines, published on the same day

The recent releases show something that a single-line project would not have: 3.0.10 and 2.6.27 were both published on 2026-10-01, and 3.0.9 on 2026-08-20.

So there are two maintained branches, 3.0 and 2.6, and the 2.6 line is still receiving releases. For an organisation running Sulu in production, that is the most operationally important fact in the release metadata, because it determines how long you can stay on the version you deployed without planning a major upgrade.

The default branch being `3.0` tells you which line the project considers current, and the presence of the upgrade notes in the repository root, `UPGRADE.md` plus `UPGRADE-1.x.md`, `UPGRADE-2.x.md` and `UPGRADE-3.x.md`, tells you how many major versions of migration documentation you would be reading.

The requirements are stated in the README: Sulu 3.0 requires a PHP version higher or equal to 8.2 and is compatible with every Symfony version from 6.4 to 7.4. The README also points at the `require` section of the `composer.json` for an up-to-date list of the requirements, which is the right pointer to follow, because a CMS framework's dependency list is long and moves.

The PHP 8.2 floor and the Symfony 6.4 to 7.4 range are the two numbers to check before anything else. A project on Symfony 6.0 or on PHP 8.1 is not a Sulu 3.0 candidate, and the 2.6 line is where such a project would look.

The bundle architecture, in the directory layout

The `src/` directory holds the framework, and inside it the `Sulu/Bundle` tree is where the platform's features live as separate bundles. The `packages/` directory holds a second set of packages with their own `assets/js` directories.

The distinction shows up in the JavaScript dependencies, and the `package.json` is a good index of the whole platform. Every bundle's front end is referenced as a local file dependency, for example `sulu-admin-bundle` from `src/Sulu/Bundle/AdminBundle/Resources/js`, and the same pattern for the audience targeting, category, contact, location, media, preview and security bundles from `src/Sulu/Bundle`, and for the custom url, page, route, search and snippet packages from `packages`.

So the administration interface is not a separate application. It is the JavaScript of the bundles, assembled by webpack, which is why the front end lives next to the PHP rather than in a different repository.

The `packages/` directory is also where the newer, more standalone functionality sits. A package with its own `assets/js` and no `src/Sulu/Bundle` counterpart is a feature that has been factored out of the core into a reusable piece, and the custom url package is the clearest example of that pattern.

That is the shape of the extension story the README describes when it says that if you are planning to extend your existing Sulu project you should visit the Sulu organisation on GitHub for a complete list of official Sulu bundles.

The JavaScript toolchain, which is not small

The `package.json` describes a front end build with several tools, and the `lint` script is the clearest statement of what the project expects of a contribution.

The script chains four checks: `lint:js` runs ESLint over the whole tree with a cache, `lint:scss` runs Stylelint over the SCSS in the bundles and packages, `flow` runs the Flow type checker, and `depcruise` runs dependency-cruiser over the same source trees with the `dependency-cruiser.json` configuration.

That four-part lint is unusual and informative. ESLint and Stylelint are the ordinary pair, but Flow and dependency-cruiser are not. Flow means the admin interface is type checked with a static type system, and the presence of a `flow-typed/` directory and a `.flowconfig` at the root confirms it. Dependency-cruiser means the architecture is enforced: the `depcruise` script points at `src/Sulu/Bundle/*/Resources/js` and `packages/*/assets/js`, so there are rules about which module may import which, and the `dependency-cruiser.json` file holds them.

Tests run under Jest, the production build is webpack in production mode, and there is a styleguidist setup with a `styleguide.config.js` for the component library, which is how the design system is documented and reviewed.

The root also holds `rector.php` for automated refactoring, `phpstan-baseline.neon` and `phpstan.dist.neon` for static analysis, `composer-dependency-analyser.php`, and a `.browserslistrc` for browser targets. The overall picture is a project with strong conventions on both sides of the stack.

Local development, and the MySQL configuration that matters

The `docker-compose.yml` at the root is a small file, and most of it is the database service, which tells you what the project expects to run against.

yaml
  database:
    image: mysql:${MYSQL_VERSION:-8.4}
    command: [ "--max_connections=1000", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_general_ci" ]
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE:-sulu}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-ChangeMe}
      MYSQL_ROOT_HOST: '%'
    volumes:
      - db-data:/var/lib/mysql

Four settings in there are deliberate rather than incidental. The default image is MySQL 8.4, so the project is developed against a current server. The max connections of 1000 is high for a development database, and it is there because a CMS with many entities and a heavy admin interface opens a lot of connections during page rendering and imports. The character set is utf8mb4, which is the only character set that supports the full Unicode range, including emoji, and the collation is utf8mb4_general_ci.

There is also a commented line offering a bind-mounted host directory for the database data instead of a named volume, and the comment explains why: it makes it harder to accidentally remove the volume and lose all the data.

The default root password is `ChangeMe` and there is a comment saying you should definitely change it in production. That is the usual shape of a development compose file, and it is worth noticing that the file itself says so.

The community, and how a contribution is expected to go

Sulu is described as a community-driven open source project backed by various partner companies, with a commitment to a fully transparent development process.

The support channels are listed with links: the official Slack channel, GitHub Discussions for questions, the Sulu Twitter account, and Stack Overflow with the official `sulu` tag.

The contribution path is spelled out in two parts. For a bug or a missing feature, file a new issue on the sulu/sulu repository with a title and a description, and if you have already found a solution you are invited to submit a pull request, which the maintainers would love to review. And there is a link to the contribution guidelines, which the README says is where to find out about the coding standards.

The `CONTRIBUTING.md` file is at the repository root, and the tooling described earlier is a fair proxy for what the guidelines say. A project with Flow types, dependency-cruiser rules, a PHPStan baseline and four lint checks in the front end is a project where the guidelines are enforced by the build.

The `SECURITY.md` file at the root is worth noting for a CMS, because a content management system is a very common target and the security reporting process is part of the project's public surface.

Where Sulu is the wrong choice

The first wrong case is a small site with a handful of pages and one editor. Sulu is a full CMS with a media manager, a content workflow, a translation model and an administration interface, and the framework in this repository is the dependency that provides all of it. A team that needs three templates and a blog would be operating a platform.

The second is a team that does not want a Symfony monolith. Sulu is a Symfony application with bundles, an admin interface built in React, and its own conventions around entities, the content model and the routing. Extending it is the intended path, but the conventions are Sulu's, and a team with a strong house style of its own will find itself writing bundles to fight them.

The third is a team that cannot take the version floor. PHP 8.2 or newer and Symfony 6.4 to 7.4 is a narrow window, and the 2.6 line exists for projects that cannot move yet, which means the real question is when you plan to move and whether the 2.6 line will still be maintained when you are ready.

The fourth is a team that wants a hosted or SaaS content platform and a different ownership model. Sulu is a self-hosted framework, and the partner companies behind it are the people who can build and host it for you, which is a commercial relationship rather than a technical one.

The fifth is a project that has decided the CMS is not where the content should live. Sulu is a PHP and MySQL system with its own admin interface, and a team whose content already lives in a git repository or a headless backend is better served by the bundle architecture used in reverse, that is, by using Sulu's components rather than Sulu.

What Sulu is genuinely strong at is the thing it names first, which is multi-lingual and multi-portal content with a translation workflow and a permission model per locale and per portal. Teams that have built that by hand know how much work it is.

Editorial conclusion

sulu/sulu suits a Symfony team that needs a CMS with first-class translation and multiple portal support, and that wants to extend it with bundles rather than patches. It does not suit a team that wants a lightweight content layer for a handful of pages, because this is the core of a full CMS with an admin interface, a media manager and a content workflow. Before adopting it, check the Symfony version you are on, since 3.0 supports 6.4 to 7.4 and requires PHP 8.2 or newer, and read `UPGRADE.md` alongside the 1.x, 2.x and 3.x upgrade notes, because the jump from 2.x to 3.0 is the one with real work in it.

Frequently asked questions

What is the difference between sulu/sulu and sulu/skeleton?

This repository is the core framework of the content management system, the functionality built into it, and therefore a dependency of all Sulu projects. The sulu/skeleton repository is the pre-configured project template to quick-start development on a new Sulu project.

What are the requirements for Sulu 3.0?

A PHP version of 8.2 or higher, and compatibility with every Symfony version from 6.4 to 7.4. The README points at the `require` section of the core framework's composer.json for the up-to-date list of requirements.

Which Sulu release lines are being maintained?

Two. The recent releases show 3.0.10 and 2.6.27 both published on 2026-10-01, and 3.0.9 on 2026-08-20, with the default branch set to `3.0`.

What does the Sulu administration interface run on?

Each bundle's front end lives next to its PHP in `src/Sulu/Bundle/*/Resources/js` or `packages/*/assets/js`, and the `package.json` references them as local file dependencies. The build is webpack, tests are Jest, type checking is Flow with a `flow-typed/` directory, and dependency-cruiser enforces architectural rules with `dependency-cruiser.json`.

How do I run Sulu locally?

The root `docker-compose.yml` provides the MySQL 8.4 database, configured with utf8mb4, a max connections of 1000 and a named volume, plus a commented option for a bind-mounted data directory. The project template itself comes from the sulu/skeleton repository, and the official documentation covers the getting started steps.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. sulu/sulu on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sulu-sulu.svg)](https://hysenlabs.com/projects/sulu-sulu)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/sulu-sulu.svg)](https://hysenlabs.com/projects/sulu-sulu)

Was this useful?