Open-source project
yiisoft/yii2-app-basic avatar
yiisoft/yii2-app-basic

yii2-app-basic and the anatomy of a Yii 2 project skeleton

Yii 2.0 Basic Application Template

675 stars776 forksPHPBSD-3-Clause

At a glance

What is it?
The Yii 2 Basic Project Template is a skeleton application with login, logout, a contact page and the directory layout every Yii 2 project starts from. It is not a framework, and its value is that it shows the conventions rather than hides them, which also means it is a template rather than a product.
Who is it for?
yii2-app-basic fits a team that has chosen Yii 2 and wants a working starting point with authentication and a contact page already wired, rather than an empty directory. It does not fit a team that wants a batteries included application framework, since the template deliberately stops at the basics and leaves the rest to you.
Can I use it commercially?
Yes. BSD-3-Clause 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 43 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 October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A skeleton meant for small projects, not a framework

The Yii 2 Basic Project Template is described as a skeleton Yii 2 application best for rapidly creating small projects. The word skeleton is the important one. It is not a starter kit with a user interface, an admin panel and a content model, and it is not the Yii framework itself.

What it does contain is the basic features including user login and logout and a contact page, plus the configurations that are commonly used, so that you can focus on adding new features to your application rather than on assembling a project from nothing.

That framing tells you the audience. If you are building a small to medium application and have already decided on Yii 2, the template saves you the work of wiring authentication, the directory layout, the console entry point and the test harness. If you have not decided on the framework, this template is not the thing to evaluate, because it will happily look like a finished application while being almost empty of features.

The repository is on Packagist as yiisoft/yii2-app-basic, and the licence is BSD 3-Clause. The default branch is master, there are no GitHub releases, and the last push was on 2026-09-10.

The tooling around it is more substantial than a bare skeleton. The top level holds a c3.php file for the code coverage tool, a codeception.yml, a composer.json, a phpstan.neon for static analysis, a rector.php for automated refactoring rules, a phpcs.xml.dist for coding standard checks, a requirements.php, a Vagrantfile with a vagrant directory, a docker-compose.yml, and both a yii and a yii.bat console entry point. That list describes a project that expects to be linted, analysed and refactored from the first day.

The directory layout is the main content of the template

The template documents its own structure, and reading that list tells you more about how a Yii 2 application is organised than any amount of prose would.

code
      assets/             contains assets definition
      commands/           contains console commands (controllers)
      config/             contains application configurations
      controllers/        contains Web controller classes
      mail/               contains view files for e-mails
      models/             contains model classes
      runtime/            contains files generated during runtime
      tests/              contains various tests for the basic application
      vendor/             contains dependent 3rd-party packages
      views/              contains view files for the Web application
      web/                contains the entry script and Web resources

Each directory has one job, and the split is the point. Controllers hold Web controller classes, views hold the view files for the Web application, and mail holds view files for e-mails, which means the markup for an email is separate from the markup for a page. Commands holds console commands, so the same application can be driven from the command line as well as from a browser.

Two directories need care. runtime holds files generated during runtime, and it has to be writable by the web server, which is the source of most of the permission problems that a new Yii 2 deployment hits. vendor holds the third-party packages that Composer installs, so it is regenerated rather than edited.

The template also adds directories that the documentation list does not mention, such as widgets and docs, plus a requirements.php file that presumably pins the environment the project expects. The same list appears in the project's Docker and CI configuration, so the layout is fixed by the tooling as well as by convention.

Installing it takes one Composer command and one secret

The minimum requirement stated for the template is that your web server supports PHP 8.2, and the installation note repeats it: the minimum required PHP version of Yii is PHP 8.2. That is a recent floor, and it is worth checking against the rest of your stack before you start, because the template does not support older PHP at all.

The Composer route is one command, and it creates the project in a directory named basic:

bash
composer create-project --prefer-dist yiisoft/yii2-app-basic basic

The prefer-dist flag tells Composer to fetch the packaged archive rather than the repository, which is the faster and more reproducible option for a template. After that the application is reachable at the URL of the basic directory under the web root:

code
http://localhost/basic/web/

The archive route exists for people who cannot use Composer. The documentation says to extract the archive file downloaded from yiiframework.com to a directory named basic directly under the web root, and then, importantly, to set the cookie validation key in the config/web.php file to some random secret string:

php
'request' => [
    // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
    'cookieValidationKey' => '<secret random string goes here>',
],

That key is not optional. Without it the cookie validation cannot work, and the inline comment in that configuration block is deliberately loud about it. This is the step people skip, and it is also the step that has to be repeated for every environment you deploy, since a key committed to a repository is a key in every clone of it.

The Docker route completes the picture and is covered in the next section.

Docker Compose, an Apache image and a writable runtime directory

The template ships a docker-compose.yml, and the service definition is short enough to read in full. The image is yiisoftware/yii2-php:8.5-apache-latest, so it is PHP 8.5 on Apache rather than the 8.2 minimum, and the application directory is bind mounted into the container:

yaml
services:
  php:
    image: yiisoftware/yii2-php:8.5-apache-latest
    volumes:
      - ~/.composer-docker/cache:/root/.composer/cache:delegated
      - ./:/app:delegated
    ports:
      - '8000:80'

Two details in that file cause real friction. The cache is a host volume in your home directory, ~/.composer-docker/cache, mapped to the Composer cache inside the container with the delegated consistency option, which is what stops every composer install from re-downloading every package. And the whole project is mounted from the host, which means the files the container writes, in runtime and in web/assets, end up owned by whatever uid the container ran as.

The healthcheck in the service definition exists precisely because of that. It checks the owner of /app/runtime and /app/web/assets, and if they are not www-data it chowns them, fixes the permissions, and then verifies that the web user can actually write into the runtime directory by touching a file and removing it. The compose file also sets the healthcheck interval to 30s, a timeout of 10s, three retries and a ten second start period.

The documented workflow is to update the vendor packages, run the installation triggers that create the cookie validation code, and then start the container:

bash
    docker-compose run --rm php composer update --prefer-dist
    docker-compose run --rm php composer install    
    docker-compose up -d

After that the application is served at http://127.0.0.1:8000, since the compose file maps container port 80 to host port 8000. The documentation notes a minimum Docker engine version of 17.04 for development and links to the volume mount performance notes, which matters on macOS and Windows where bind mounts are slow without the caching options.

The database is yours to create, and the config file says so

The database section is short, and it contains the most common first-day failure in a Yii 2 project. You edit config/db.php with real data:

php
return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '1234',
    'charset' => 'utf8',
];

The note under it is unambiguous: Yii will not create the database for you, this has to be done manually before you can access it. The example uses MySQL with the classic root credentials, which is fine for a local environment and obviously something to change before the application goes anywhere real.

The other two notes in that section are quieter and matter more over time. You are told to check and edit the other files in the config directory to customise the application as required, which is a reminder that the config directory is the place where this project keeps its decisions, and to refer to the README in the tests directory for information specific to the basic application tests, which is a hint that the test suite is part of the template rather than something you add later.

The consequence for a team is that the template gives you a wiring convention rather than a schema. There is no migration, no seeder and no user table with a role column. You create the database, you create the tables, and you decide what the users table looks like, which means the login and logout that the template ships with are a starting point that you will probably rewrite once your own user model exists.

Three Codeception suites and a local web server for the browser ones

Tests are located in the tests directory and are developed with the Codeception PHP Testing Framework. By default there are three suites, unit, functional and acceptance.

The unit and functional suites run against the php-builtin environment with a single command:

bash
vendor/bin/codecept run --env php-builtin

The documentation is clear about the split. Unit tests are testing the system components, while functional tests are for testing user interaction. That is the Codeception distinction: a unit test calls your classes directly, a functional test drives the application through its own HTTP layer.

Acceptance tests are configured separately in tests/Acceptance.suite.yml, and by default they use the PhpBrowser module, which drives the built-in PHP web server started via the php-builtin environment. Running them uses either the composer script or the suite name directly:

bash
composer tests
vendor/bin/codecept run Acceptance --env php-builtin

For a real browser you switch the acceptance suite to the WebDriver module, and tests/Acceptance.suite.yml contains an example WebDriver configuration that is commented out. So the option exists and is documented, but it is off by default, which keeps the default test run fast and free of a browser dependency.

Running the same tests inside the container uses the Docker Compose exec form:

bash
    docker compose exec -T php vendor/bin/codecept build
    docker compose exec -T php vendor/bin/codecept run

The build step is not optional in that pair. Codeception generates the actor classes from the suite configuration, and running without a build first tends to fail in a way that looks like a missing dependency.

What a template like this costs to keep

The question worth asking is what happens after the first week. A template is not a dependency, so there is no composer update that pulls in a newer version of your application's skeleton, and there is no upstream to merge from once you start changing files. The template is a starting copy, and the maintenance cost is the cost of keeping a fork of a skeleton alive.

There are two sane ways to handle that, and both are visible in the repository. The first is to treat the template as a reference and delete what you do not need, so that what remains is code you own outright. The second is to keep the template as a composer project and pull in changes selectively, which the Packagist listing and the create-project command make possible.

The BSD 3-Clause licence is the permissive case here, and it is the licence of the template itself rather than of Yii, which is a separate project with its own terms. Read both if the application is commercial.

The other cost is the PHP floor. The template requires PHP 8.2, its Docker image is on 8.5, and the code is checked by phpstan and rector, which means the toolchain expects regular maintenance rather than a one-off scaffold. That is fine if you have chosen Yii 2 deliberately, and it is a reason to reconsider if you have not, because a skeleton with a hard PHP floor and a full static analysis setup is a commitment to a maintained codebase rather than a script.

The honest summary is that yii2-app-basic is at its best on day one and ordinary on day one hundred. It saves you a day of wiring and then becomes your own code, which is exactly what a skeleton should do, and exactly why you should treat the choice of framework separately from the choice of template.

Editorial conclusion

yii2-app-basic fits a team that has chosen Yii 2 and wants a working starting point with authentication and a contact page already wired, rather than an empty directory. It does not fit a team that wants a batteries included application framework, since the template deliberately stops at the basics and leaves the rest to you. Before starting a project from it, read config/web.php and set the cookie validation key, remember that the database has to be created by hand before config/db.php will work, and note that the template is versioned on Packagist as a project, not a library.

Frequently asked questions

How do I install the Yii 2 Basic Project Template?

Run composer create-project --prefer-dist yiisoft/yii2-app-basic basic, then open http://localhost/basic/web/ if the basic directory sits directly under the web root. You can also extract the archive from yiiframework.com into a directory named basic.

What PHP version does yii2-app-basic require?

The template requires PHP 8.2, both in the requirements section and in the installation note. The bundled Docker image runs PHP 8.5 on Apache.

Why does a new Yii 2 project fail to connect to the database?

Yii will not create the database for you, it has to be done manually before you can access it. You set the real credentials in config/db.php, for example with a dsn, username, password and charset.

How do I run the tests in yii2-app-basic?

Tests use the Codeception PHP Testing Framework with unit, functional and acceptance suites. Run vendor/bin/codecept run --env php-builtin for unit and functional tests, and switch the acceptance suite to the WebDriver module for a real browser.

What licence is the Yii 2 Basic Project Template released under?

BSD 3-Clause, with the licence text held in the LICENSE.md file at the repository root. The licence of the Yii framework itself is a separate matter.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. yiisoft/yii2-app-basic 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/yiisoft-yii2-app-basic.svg)](https://hysenlabs.com/projects/yiisoft-yii2-app-basic)

Was this useful?