Evermade is a one-stop digital agency designing, creating, marketing, optimizing and maintaining web and mobile services, sites and ecommerce stores. WordPress is at our core, but we work with other platforms too. I’m the CTO of Evermade and in this post, I’m explaining how our development team operates and what tools we use. This is the fourth state of development post. The previous versions are available here: 2017, 2019, and 2020.
In my opinion, these blog posts have been very beneficial and that’s also what I’ve been told. Pretty much every developer candidate who applied to Evermade has read these before coming to an interview. I also hope this helps someone in the developer community – in fact, I know it does. I have got private messages from people working on other agencies about these and we’ve had some really good discussions.
Our dev team
Let’s begin with our dev team. At the time of writing this, we have 50 employees, and half of them are developers. Our company is split into account teams. Each team has its own clients and all the professionals required to build services: project managers, designers, developers, analysts, and SEO specialists. Our team size is roughly ten people and each team usually has 4-5 developers.
In addition to account teams, we have one team dedicated to ongoing work and DevOps, a support team, a growth team, and an admin team.
As a developer, you work in one of these teams. In every account team, we have a lead developer who is responsible for running dev operations in their team. This work includes supporting developers across projects, coaching team members, running dev meetings, and so on. In addition, we have senior developers who usually have some extended responsibilities like taking care of some internal tools or coaching others. As a CTO, I’m doing my best to take care that all these operations run smoothly. And of course, I’m also responsible for writing these kinds of posts…
Our core tech
Evermade is a WordPress agency. We do not blindly believe that a single tool or technology is a solution to all problems and we constantly explore other solutions as well – but still, 80% of our revenue comes from WordPress projects. We also work with HubSpot CMS and have a dedicated team for HubSpot development. When it comes to other CMS systems, we have used Contentful on a few projects.
Get-togethers and & trainings
Sharing knowledge and inspiring others is a very important part of our competence. We have various channels for sharing and collaborating.
- We have organized dev meetings for as long as I can remember. Currently, these are happening once a month. A dev meet is an hour-long session where we share updates on recent changes and we also have one or more small presentations about various topics.
- Evermade is split into small account teams. Each team has roughly five developers and these groups also have their own team dev meetings.
- We are utilizing the OKR model at Evermade. Once a month we get together as a competence for a contributor morning. It’s a set time for pushing OKR objectives forward.
- In addition to these repeating events, we organize additional training. For those sessions, someone prepares a presentation (the topics vary). We have had sessions about integrations, NGINX caching, accessibility, and so on.
One very important thing is also our #dev-support Slack channel. It’s a channel reserved only for dev issues. If you have a question, there will always be an answer on #dev-support.
We also have a learning day. That means that you are allowed to use one day in a month for learning. You can decide on the topic as long as it at least somehow relates to our work. Learning day is not very strict – it’s more like a guideline. You can have two half days or travel to a conference. Whatever is the best for your learning.
Working with WordPress
Development in the cloud
The majority of our development happens on cloud servers. We are using UpCloud as our infra provider and each developer has their own Ubuntu instance running. The server runs our sites with Docker. All preprocessing and building happen on that server, not locally.
There are some clear benefits of this approach:
- The biggest thing is that environments are equal. If something weird happens, we can be quite certain that the issue is not caused by a different environment configuration.
- Everyone can access all instances. It’s easy to help a friend out and continue others’ work if someone is unavailable.
- We can work with virtually any laptop available.
- A centralized cloud environment is more secure compared to the option where projects are stored locally on laptops.
All of our developers use Visual Studio Code for development which has excellent support for remote file editing. It feels local.
Cloud-based development does, of course, come with some drawbacks:
- Running cloud servers comes with some fixed costs.
- Some development tools require special configuration since the dev environment is not run locally.
- It requires a stable internet connection.
However, you are not forced to work on the remote instance at Evermade. In some projects, like React-only projects, it doesn’t really make sense. It’s mostly down to the preference of our developers.
Our environments runs on Docker. We call this system Mayhem. Docker configs take care of running NGINX, FastCGI cache, PHP-FPM and MariaDB. We have development, staging, and production docker configurations on the project repo. This allows us to version environment configuration and it also ensures that environments are equal. This also makes moving services around trivial. We have built an image we can pull & run it to anywhere.
Previously, we also had a lot of tooling bundled into Docker containers, like node. But life is a bit easier nowadays with node version management tools like n so we install these tools locally.
We have automated some of the most common Docker tasks with our internal cli tool called em helper. It makes it easier to build and spin up projects and do some automation tasks like database pulling.
Base theme and Gutenberg
We have recently renewed our base theme to be fully Gutenberg-compatible. We call it Everberg. The philosophy of the theme is to be almost ready to use out of the box and also be a good foundation for further development, so it’s not just a boilerplate. We have also moved a lot of stuff from our theme to plugins. Business logic is separated into its own plugin (see Features below) and each custom block is a plugin.
This has made the theme itself very lightweight. It has templates for some fundamental views and a webpack-based build process. It also hides unwanted stuff from the admin. Everberg has styling for the core Gutenberg blocks.
We made the decision not to blindly use ACF to create blocks which seems to be the standard path in the industry. We worked with ACF flexible layouts for years, so it would have been easy to just start creating Gutenberg blocks with ACF. There would be nothing wrong with that. On the other hand, there’s no real reason to use it either. WordPress has very good documentation for creating blocks with native tools, and the user experience is usually better with native blocks compared to ACF blocks.
The development experience is a bit different with native blocks. Previously with ACF flexible content, we always created a block. It was straightforward and easy. Now with Gutenberg, you have multiple choices:
- Native block with static frontend
- Native block with server-side rendering
- Native block with React frontend
- Block patterns consisting of multiple blocks
- ACF blocks
Working with Gutenberg is more flexible than working with ACF and requires a bit of thinking before jumping into code.
Native blocks and having each block as a separate plugin forces us to decouple functionality. It then allows us to copy and paste blocks between projects, which clearly opens some productivity possibilities.
Plugins are the greatest and also the most horrible part of the WordPress ecosystem. It’s nice to have a lot of tools available, But it’s also difficult trying to pick out properly made, reliable plugins from the mass.
The general rule of thumb is that we try to avoid installing plugins whenever we can. We pick our tools very carefully. Sometimes, a single hook will do the thing and no plugin is required at all.
There are, however, some useful plugins we install on almost every project:
I also must admit one thing. We sometimes use Wordfence. I know it’s a very blamed plugin, it has some performance issues, it’s known to be causing weird behaviour and it has a dark history of being a security issue in itself. However, it offers some easy plug-and-play solutions for some specific security cases, like protecting sites against unwanted admin behaviour.
Separation of concerns: Features plugin
For custom functionality, we’ve introduced a wildly named plugin called Evermade Features. This is actually a new thing compared to previous years. Previously, we bundled most of the functionality to our theme, but now the idea is to separate functionality to it’s own plugin.
The plugin does things like:
- Defines custom post types
- Defines custom taxonomies
- Adds CLI commands
- Adds admin-ajax and REST endpoints
- Does all other project-specific things like custom hooks and integrations
A few words about React
We mainly use React for three things:
- Creating Gutenberg blocks
- Creating complex frontend user interfaces (like filtered views, multi-step forms, etc.)
- Bespoke applications like PWAs
We have made boilerplates for blocks and block frontends which can be extended or modified for your needs. I’m not going too deep into our React implementations but it’s safe to say that the average developer needs at least basic React knowledge at Evermade.
For applications, we do not have anything ready-made and our dev team can make the best decisions in each individual project.
Deployments and server infra
Our primary hosting solution is to run a site on UpCloud’s data center. The infrastructure is created and maintained by us. Essentially, it means a farm of Linux servers each running docker containers. We have evaluated WordPress-as-a-service platforms like Seravo and WP-Engine, but decided to run sites on our own. That way we have full control (and of course responsibility) to run our sites in the way we want. This also means that we have in-house DevOps knowledge, which is a very valuable asset. Usually, large-scale sites require customized infra, and it’s important for us to be able to deliver.
We monitor our sites’ uptime and server resource usage with Hetrix Tools. In addition to that, we have a custom-made solution to collect diagnostics from sites (like plugin versions). We collect information about the “state of our fleet” to Podio which is a highly customizable platform to organize data.
In a developer’s mind, automated testing is usually cool and something everyone should always be doing. In reality, when working on websites (mostly non-functional), creating proper end-to-end testing is not something worthy of doing. However, we have been creating automated end-to-end tests for some websites, especially for ecommerce and lead-generation functions. Automated tests have prevented us to deploy broken code to production. For end-to-end testing, we use Cypress.io integrated into Bitbucket Pipelines.
Maintenance and continuous development
When a site project is finished and the site is launched, it’s moved to our Care team. Care helps our client to further develop their sites. They also take care of maintaining the site and updating versions. I often call our Care team the “backbone of our company” and I really mean it. Our Care team
- makes clients happy by providing quick solutions for their needs and
- makes project teams happy by allowing them to focus on their ongoing work.
When interviewing developers, having a dedicated team for existing clients and allowing people to focus on projects has been proven to be one of our biggest benefits.
Please check this blog post about care (in Finnish).
We also have some non-development tools that might still be interesting for developers:
- Favro for project management
- Google Workspace for email, calendar and files
- Figma for layouts
- Slack for communication (and Teams for some clients)
Constant improvement is required in this industry. On the other hand, internal development is time-consuming and we need to keep focusing on the right things. These are currently on our table:
- Deeper Gutenberg knowledge.
- Automating processes for Evermade Care (automatic updates, testing).
- Open-sourcing our tools. We have been talking about this for ages, but this time it’s really happening. I promise.
- More internal training.
- An integration boilerplate, because we do a lot of complex integrations.
- Personalization and A/B-testing tools together with Liana.
How about HubSpot?
I mentioned HubSpot and its emerging importance but it’s not covered in this post. It’s a whole separate story and deserves its own blog post. This will be published separately, so stay tuned.
That’s it this time. It’s always nice to escape from daily routines and stop for a while and think about where we are at. For me, writing these posts is always rewarding. It really shows us how much we have progressed in the past years 🙂
Ps. Now that I have got your attention… If you are looking for a new challenge, please check out our open positions!