CLI tool
symfony/demo avatar
symfony/demo

The symfony demo promises three install methods, documents two, and ships both a PHPStan baseline and four dotenv files

Symfony Demo Application

2,620 stars1,676 forksPHPMIT

At a glance

What is it?
symfony/demo is a reference application for Symfony best practices whose tree is generated by recipes and locked twice over, once for Flex and once for Composer. Its test suite runs through a binary in bin/, its JavaScript arrives through an import map, and its installation section counts three options while showing two.
Who is it for?
Read this project as documentation with a working build attached, not as a starter kit to copy blindly. It earns its keep when you want to see how a framework's recommended structure looks when every layer is filled in, and the recipe lock plus the committed dependency lock mean a fresh checkout resolves to a known state.
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 8 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 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • symfony/demo2,620 ★ · +0
Star history
Repository2026-10-042026-11-14
symfony/demo2.6k2.6k

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

Editorial analysis

The installation section promises three methods and shows two

The text says there are three different ways of installing the project depending on your needs, then presents two, both labelled as options. Option 1 is the Symfony CLI:

bash
symfony new --demo my_project

Option 2 is Composer, and it carries two routes of its own:

bash
# you can create a new project based on the Symfony Demo project...
composer create-project symfony/symfony-demo my_project

# ...or you can clone the code repository and install its dependencies
git clone https://github.com/symfony/demo.git my_project
cd my_project/
composer install

So three install commands are shown and two options are labelled, which is how a reader arrives expecting a third choice that does not exist on the page. The three commands are also not equivalent in what you get. The CLI path and the create-project path fetch a packaged project from a registry, while the clone path gives you the repository as it stands on its default branch, which is the one path that also brings whatever is in the working tree rather than what was packaged.

Both run modes want port 8000, one encrypted and one not

The usage section offers two ways to serve the application and then says no configuration is needed before running it. With the Symfony CLI it is one command, and the browser URL is given as https on localhost port 8000 by default:

bash
cd my_project/
symfony serve

The alternative is any web server, and the local shortcut for that is PHP's own built-in server pointed at the public directory:

bash
cd my_project/
php -S localhost:8000 -t public/

The same port appears in both, and the two differ in a way that matters when something goes wrong: the CLI serves over TLS, the built-in server serves plain HTTP on the identical port. A bookmark or a cookie set during one will not behave the same under the other, and switching between the two modes without clearing state is a common source of confusion. The public directory being the document root is the other fact the second command makes explicit.

Two lock files say who assembled this tree

The root carries both a recipe lock and a dependency lock, and they answer different questions. The recipe lock is the record of which configuration files each Flex recipe created, which is why the tree is full of small files nobody hand wrote: environment templates, package configuration, translation wiring, front end entry points. That record is what lets a maintainer see what a package expects to own, and it is also why deleting one of those files by hand is not the same as removing the package. The dependency lock is committed too, which a normal application would not do, and for a reference application it is the point: the exact dependency set this demo was built against is visible and reproducible rather than whatever resolves today. Between them, the two locks make the tree auditable in a way an application starter rarely is.

Four dotenv files ship in the tree while the page says nothing needs configuring

The page's reassurance is that there is no need to configure anything before running the application, and the tree appears to agree: there is no configuration step in the installation or usage sections, and no step asks you to create an environment file. Yet the root already contains four of them, one general, one for the development environment, one named for a local demo variant, and one for tests. That layering is the framework's default arrangement, and having it pre-populated is the point: a reader who forks this project does not have to discover which variables exist or guess their names. The file named for the local demo variant is the one that does the most work for a newcomer, since it is what makes a copied checkout run without anyone writing a dotenv file first. The result is a project that asks for no setup step while carrying the setup for every environment it supports.

A static analysis baseline ships with the reference application

Two analysis configurations sit at the root: one for PHPStan and one for the code style fixer, plus a baseline file beside the PHPStan configuration. A baseline is the list of findings a tool reports that the project has decided to accept rather than fix, and it is normally a sign of accumulated debt. Shipping one in a reference application is a deliberate choice with a clear cost: the demo is exemplary in structure and explicitly not exemplary in having zero outstanding analysis findings, so a reader copying its configuration inherits a file that will silently absorb new issues until someone prunes it. The code style configuration is the counterpart, and it is the more useful of the two to copy, since a project that never had debt in the first place has nothing to baseline. Together the two files describe a project that chose to be honest about its tool output rather than quiet about it.

Tests run through a binary in bin rather than a global tool

The test section is one command and one file:

bash
cd my_project/
./bin/phpunit

The runner is invoked from the project's own bin directory, not as a globally installed command, and the root holds the test configuration file with the distribution suffix convention that tells a machine not to edit it. That arrangement means the version of the test framework you get is the one the dependency lock pins, which is the same reasoning behind the committed lock and worth copying. It also means a reader who has installed phpunit globally, or who expects to run the suite with a different version, will not get the result this project validated. The tests live in their own directory beside the source, and the suite is the piece of this repository that most supports its claim to be a reference rather than a sketch.

Front end code arrives through an import map

There is an import map file at the root and an assets directory beside it, and no front end bundler configuration anywhere in the tree. That combination is the modern Symfony answer to shipping JavaScript without a build step: the import map is a PHP file that tells the browser how to resolve bare module names, so the browser fetches the dependencies directly and the project carries no node manifest and no bundler. For a reference application the effect is that a reader can open a page, read the import map, and know exactly which script version the page will load. It also means no transpilation and no tree shaking, which is a real trade rather than an oversight, and one that is easy to miss when the same application also carries a code style fixer and a static analysis baseline for its server side code.

The demo carries its own release line

The repository is versioned separately from the framework it demonstrates, with tags at 3.1.0 in June 2026, 3.0.2 in May 2026 and 3.0.1 in February 2026, and the last commit is dated 2026-09-16. That matters when you are reading the application as documentation, because the code in the tree reflects whatever the framework's current recommendations were at that release, not the version you happen to have installed elsewhere. The page also points its own homepage at the framework's main site and its best practices guide outward to the official book, so the demo is positioned as a companion to that documentation rather than a replacement for it. Its own one-line description, Symfony Demo Application, matches its heading exactly, which tells you there is no marketing distinction between the two.

Editorial conclusion

Read this project as documentation with a working build attached, not as a starter kit to copy blindly. It earns its keep when you want to see how a framework's recommended structure looks when every layer is filled in, and the recipe lock plus the committed dependency lock mean a fresh checkout resolves to a known state. Three things to check before basing a project on it. The installation section promises three methods and shows two, so do not expect a third option to exist. Running the suite depends on the phpunit binary inside bin rather than on anything you have installed, which is the correct choice and will surprise anyone used to a global runner. And the dotenv files in the tree, plus the PHPStan baseline, tell you the defaults are curated: the reference application accepts a recorded set of static analysis findings rather than a clean sheet. Anything you build here inherits those decisions.

Frequently asked questions

What is the symfony/demo application for?

It is a reference application created to show how to develop applications following the Symfony best practices. The page points to the official Symfony Book for the same practices in prose form.

What do I need before running the Symfony demo?

PHP 8.2.0 or higher, the PDO-SQLite PHP extension enabled, and the usual Symfony application requirements. No configuration is needed before running it, because the environment files are already in the tree.

How do I install the Symfony demo application?

With the Symfony CLI using symfony new --demo my_project, or with Composer using composer create-project symfony/symfony-demo my_project, or by cloning the repository into my_project and running composer install inside it.

How do I serve and test the Symfony demo?

Serve it with symfony serve, which listens on https://localhost:8000 by default, or with php -S localhost:8000 -t public/ for plain HTTP. Run the tests with ./bin/phpunit from the project directory.

Which database does the Symfony demo use?

The only database requirement it names is the PDO-SQLite PHP extension, so a SQLite setup is what a fresh checkout expects. A data directory sits at the root of the tree.

What are the lock files in the Symfony demo for?

The recipe lock records which configuration files each package recipe created, and the committed Composer lock pins the dependency versions this reference application was built against, which makes a fresh checkout resolve to a known state.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. symfony/demo 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/symfony-demo.svg)](https://hysenlabs.com/projects/symfony-demo)

Star history chart for your README

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

Was this useful?