Project structuring

Overview

One of the most important things when starting a project is deciding on a decent folder structure.

Decisions made at the start have a big impact on how maintainable your project is in the long run, with bad initial choices having hideous consequences for even tiny decisions later on.

After years of refining my process and taking inspiration from a variety of technologies, methodologies and frameworks, I have now settled on a siloed structure that at its core has 4 base folders:

/assets
/content
/resources
/vendor

The reason for this is separation of concerns, based on 3 main criteria:

  1. what is the content type?
  2. who is responsible for the content?
  3. how often the content will be updated?

Breakdown

Broken down, this looks like so:

  • /assets
    • developer / designer
    • project-specific graphics, styles and scripts
    • many changes in development, few after go-live
  • /content
    • cms
    • final output, such as static HTML or rendered content
    • will be updated as and when there needs to be new content
  • /resources
    • developer / cms / client
    • templates, data, images or uploaded files that are subject to ongoing client-requirements
    • will be updated as and when there needs to be new content
  • /vendor
    • developer / 3rd parties
    • all frameworks, plugins, and 3rd party scripts
    • some changes in development, few changes after go-live

Particulars

It should be clear how /assets differ from /resources. Assets are like the trunk of the tree, permanent and provide structure, where resources are like the leaves, they change with the seasons and are constantly updated.

/vendor (a framework convention) can further be broken out into sub-folders, per technology such as /js,/php/css etc

If you use NPM, then your /vendor folder will of course be /node_modules.

Vendor customisations should go in /assets/vendor. This allows you to easily layer vendor-specific customisation (e.g. themes, enhancements, monkey-patches) between vendor and project code.

I also generally add a vendor’s full folder structure, documentation, assets, everything. That way it’s easy to use their tests and demos to check if something you’ve customised is broken because of you, or them.

Of course it’s easy to add new top level folders like /tests as well, as having the minutiae siloed-out means there’s never any clutter in the root.

If developing an app I generally remove /content and replace it with /app, where all application-specific content goes. This folder (like assets or vendor) can be further broken down – I usually do it by file type if it’s a JavaScript app, or if something like PHP, it would be however the framework requires.

One of the best things about this setup is that it makes version control really intuitive – you can quickly commit or check what kind of files have had updates, as the the asset typeowner, orfrequency of update is inferred by the files’ root folder.

Real world

A final content-driven project structure, such as a static website, might look like this:

/assets
	/css
	/fonts
	/img
	/js
	/sass (or less)
	/vendor
		/heapbox
/content
	/about
	/product
	/team
/resources
	/data
	/files
	/images
/vendor
	/js
		/ie
		/jquery
		/retina
	/php
		/mailchimp
index.html

And a JavaScript app with a PHP back end, run off something like Slim, might look like this:

/app
	/js
		/components
		/models
		/views
		/utils
	/html
	/php
		/config
		/controllers
		/includes
		/models
/assets
	/css
	/fonts
	/img
	/js
	/sass (or less)
	/vendor
		/ace
		/jquery-ui
/vendor
	/js
		/ace
		/jquery
		/retina
	/php
		/Hybrid
		/Idiorm
		/Paris
		/Slim
		/Twig
/tests
index.php

The great thing about this setup is that everything has a home.

There’s not been one time since using this folder layout that I’ve thought “where should something go?”, though I’m sure that might change if and when my development practices do, especially as the kind of projects i’m taking on increasingly look to be using build tools like Grunt and Gulp.

Leave a Comment