What Matrix customization involves
Matrix customization covers four kinds of work: branding and configuring Element clients, building Synapse pluggable modules, writing bots and integrations, and keeping all of those pieces working as Synapse changes. Each has a different skill profile and a different risk. Client branding is mostly configuration. Synapse modules run inside the homeserver process, so a defect there affects every user. Bots sit outside the server and talk to it through its client-server API. Test and maintenance work ties the three together, and it is the part teams most often underestimate.
Customization usually starts from one of four triggers. The first is a new organization-wide deployment, where the client must match corporate identity and policy from the first day. The second is a move away from an off-the-shelf client setup, where the default Element experience no longer fits how staff work. The third is a need for internal integrations, such as alerting from monitoring tools or account workflows like onboarding and offboarding. The fourth is a compliance requirement to control what the client shows, for example hiding features, restricting registration prompts or limiting what a user can see about other accounts.
Many teams can handle client branding and simple bots in-house, provided one or two engineers own them. Synapse module work and upgrade testing are where outside help is most often requested, because a module written against one release can break on the next, and rollback is harder once database schema changes have run. Before deciding, ask who will maintain each custom piece after handover, and which Synapse release each one was tested against.
The sections that follow cover the build decisions for each area, the effort drivers that shape a fixed-scope quote, and the testing needed after each upgrade. Confirm the current Element client configuration options and Synapse module interfaces against the versions you plan to run, since both change between releases.
What the work includes
Matrix customization covers four work packages that touch the client, the homeserver and the surrounding automation, plus the handover that lets your team keep them working. The scope is agreed in writing before work starts, so each item below is either in or out of the quote.
Element client branding and configuration
We set the product name, logos, default settings and the features that are switched on or off for your users. The exact mechanism depends on the Element version you run, so we confirm the configuration keys against that release before anything is changed. Check which settings are enforced for all users and which can still be overridden by individuals.
Synapse pluggable modules
We build custom modules for spam checking, account validity, custom authentication or event hooks against the module interfaces of the Synapse version you choose. Each module is tied to that version, so the build records which interfaces it uses. Ask how each module behaves when Synapse changes those interfaces and who owns the fix.
Bots and integrations
We define each bot account, its permissions, the rooms it joins and how it authenticates to the homeserver. Access tokens, password handling and room membership are documented so a departing administrator does not leave an unmanaged account behind. Confirm which bot actions must be audited and where those logs are kept.
Regression and upgrade test harness
We provide scripted tests that exercise custom modules, bots and client configuration after each Synapse or Element release. The harness runs in a staging environment that mirrors production's database and worker layout. Confirm with us which test cases cover your critical rooms and which must be extended by your team.
Handover package
You receive source repositories, build and deployment runbooks, a compatibility matrix by Synapse version and the test scripts. The matrix records which module and bot builds work with which homeserver and client releases. Ask for named owners for each repository and a review of the runbooks by your operations team before the engagement closes.
What drives cost and duration
This table lists the factors that most change the effort of a Matrix customization project, why each one matters, and how to keep it under control.
| Driver | Why it matters | How to keep it down |
|---|---|---|
| Number of client builds | Each Element client build, such as web, desktop or mobile, needs its own packaging, testing and release steps. Separate branding for each build multiplies design and QA work. | Limit custom branding to one primary build first, then add others in later phases. Confirm which client builds your users actually need. |
| Synapse modules and their hooks | Pluggable modules that hook into core event or authentication paths need the most test effort, because a defect there can affect every message or login. | Keep modules to the smallest set of hooks needed. Prefer modules that run outside the event path where the requirement allows. |
| Bots and integrations | Each bot or integration depends on an upstream system with its own API, credentials, rate limits and change schedule, which adds ongoing maintenance. | Inventory every bot with its owner, upstream system and credential model. Retire or merge bots that duplicate each other. |
| Identity integration | Whether authentication runs through Synapse (OIDC, SAML or CAS) or through Matrix Authentication Service changes the configuration, testing and user migration work. | Decide the identity architecture before building modules. Confirm which upstream provider and protocol your organization already supports. |
| Target Synapse version and distance from current release | Synapse documents schema changes between releases that can make rollback difficult. A custom build pinned far behind the current release typically needs more catch-up work at each upgrade. | Pin a supported Synapse version, track the upgrade notes for each release, and schedule regular upgrades instead of large jumps. Confirm the current release with the Synapse GitHub releases page at project start. |
| Deployment model | A plain VM, a Kubernetes deployment with Helm charts, or Element Server Suite each change how modules, workers and configuration are packaged and tested. | Choose the deployment model that your platform team already operates. Avoid adding a second deployment method for custom components. |
| Environments and release gates | Each environment (development, test, staging, production) and each approval gate adds deployment and verification steps for every custom component. | Automate deployment and smoke tests. Keep the number of gates to what your change process requires. |
| Compliance and confidentiality requirements | Regulated or confidential deployments add review of module code, evidence of configuration, access logs and change records. This work recurs at every release. | Agree the evidence list at scoping. Generate configuration and change records as part of the release process rather than afterward. |
Project phases and outputs
The sequence moves a Matrix customization from agreed requirements to a tested, documented, upgrade-ready set of custom pieces that your internal owners can run.
Discover requirements and inventory
We agree the list of branding and feature changes for the Element clients, inventory the Synapse modules and bots you need, and confirm the target Synapse and client versions. The output is a written requirements list with a module and bot inventory, which you approve before design starts.
Design interfaces, permissions and versioning
We produce a module interface plan that defines how each custom module hooks into Synapse, a bot permission model that sets what each bot may read and do, and a version compatibility policy that states which Synapse and client releases each custom piece supports. Design is complete when you have signed off all three documents.
Build branded clients, modules and bots
We build the branded client builds, the Synapse modules, and the bots with their configuration, all kept in a version-controlled repository so every change is reviewed and traceable. The step closes when the repository builds reproducibly and the configuration for each environment is documented.
Test on a staging homeserver
We run automated checks against a staging homeserver on the target Synapse version, covering modules, bot permissions and configuration, and then complete a manual client review of branding and feature behavior. The output is a test record listing each check, its result and any open defects, which you accept before deployment.
Deploy, document and hand over
We roll the approved build out to production, write runbooks for routine operation and common faults, and train your internal owners to run the custom pieces. Handover is complete when the owners have performed the runbook steps themselves and accepted the documentation.
Rehearse the next Synapse upgrade
We document a process for running the custom modules, bots and client builds against the next Synapse release on a non-production homeserver before any production upgrade. The output is a rehearsal report recording what broke, what was changed and whether the custom pieces pass, which guides the production upgrade decision.
What teams keep in-house and what they outsource
This table shows who usually owns each part of a Matrix customization, the skills each part needs, and what to watch for, so you can split the work between your team and a partner.
| Work part | Usual owner | Skills needed | Note |
|---|---|---|---|
| Branding assets and content decisions | In-house | Design, brand governance, internal communications | Keep logos, colors, and wording under your control so changes do not need engineering time. |
| Client configuration and feature policy | Shared | Matrix administration, Element client configuration | Decide which features, integrations, and defaults users get, then record them as configuration your admins can reproduce. |
| Synapse module development | Often outsourced | Python, Synapse internals, module interfaces for the target version | Modules run inside the homeserver process, so each Synapse release can break them; confirm the module interface for your exact version first. |
| Bot and integration development | Either side | API design, security controls for the upstream system, secrets handling | Bots act with credentials into other systems, so review their permissions and token storage as part of the build. |
| Test harness and upgrade rehearsal | Often outsourced at first, then handed over | CI pipelines, Synapse operations, staging environments | Rehearse each Synapse upgrade against your modules and clients before production; the partner should transfer the harness to your team. |
| Ongoing ownership of modules after handover | In-house | Python maintenance, dependency updates, on-call discipline | Assign named owners and align your team with the Synapse release cadence, since module code must track each homeserver release. |
What goes wrong and how to prevent it
Most failures in custom Matrix work come from release changes, runtime support dates, build practices, access rights and handover gaps. Element Server Suite and Synapse Pro are separate products with their own release arrangements, so confirm which build the custom work targets before design begins.
Module breaks after a Synapse upgrade
A custom module written against one Synapse version can fail quietly after an upgrade, for example when an internal interface it calls changes. Prevent this with a pinned compatibility matrix that records which Synapse release each module supports, plus automated tests run against every new release before rollout. Ask who runs those tests and where the results are kept.
Failed upgrades with no easy return
The Synapse upgrade notes warn that rolling back can be difficult because releases change the database schema. When custom code is also involved, a failed upgrade may leave no quick path back. Take a database backup before every upgrade and rehearse the full upgrade on a copy of production, including the custom modules, before scheduling the production change.
Forced upgrades from end-of-life runtimes
Synapse drops support for Python and PostgreSQL versions once they reach upstream end of life, so an aging runtime can force a Synapse upgrade sooner than planned. The upgrade notes list minimums, such as Python 3.10 for 1.142.0 and PostgreSQL 14 for 1.143.0. Track these minimums against your host and database lifecycles, and schedule runtime upgrades before the Synapse release that needs them.
Branding leaking across builds and channels
Branding changes made for one client build can leak into a non-branded build, and a theme edit can break the update channel that clients use to receive new versions. Produce branded and unbranded artifacts from one build pipeline with separate configuration, and sign each artifact so administrators can verify what they install.
Bots with excess permissions or plain-text secrets
A bot often joins many rooms and holds an access token with more room permissions than its task needs, and its credentials may sit in plain configuration files. Run each bot under a dedicated least-privilege account limited to the rooms it serves, and load tokens from a secrets store at runtime. Review power levels and rotate tokens on a fixed schedule.
Custom code with no owner after handover
Custom modules, bots and client themes often outlive the team that wrote them. Without a named owner, nobody knows which Synapse version they target, how to deploy them, or what to do when tests fail. Assign an owner for each component, write a runbook covering install, upgrade and rollback, and keep one shared test suite that the internal team can run.
How the work changes by starting point
A new Synapse deployment with no existing client customizations has the simplest starting point, but the customization decisions still need to be made before the first build. The work is mostly design and a clean baseline.
- Extra work: choose the customization points early (Element client branding, one or more pluggable modules, bots), and set up a build and test pipeline for them before users arrive.
- Risks: adding custom modules before the homeserver version and dependency policy is settled, which makes the first upgrade harder.
- Risks: tying branding or client forks to a version that will be replaced within a short release cycle.
- Questions to answer: which features must be custom at launch, who owns each custom piece after handover, and how often will the team take upstream releases?
- Questions to answer: will the custom code live in a repository the client controls, with its own tests and release process?
A move from an older Synapse version with custom modules already in use is the highest-risk starting point. The work starts with a version gap analysis and ends with a staged upgrade that proves each custom module still loads and behaves correctly.
- Extra work: inventory every custom module, its interface assumptions and the Synapse version it was built against, then map that against the release notes between the current and target versions.
- Extra work: plan a staged upgrade through intermediate versions where the upgrade notes require it, with a test environment restored from a recent database copy.
- Risks: database schema changes between releases can make rollback difficult, so a verified backup and a restore test come before the first step.
- Risks: Python and PostgreSQL minimums can rise with each release, which can force operating system or database upgrades alongside the homeserver.
- Questions to answer: what is the current version, what is the target, which modules are in use, and who maintains each one?
An environment on Kubernetes using Helm charts changes how custom images and configuration reach the cluster. The customization work becomes partly a delivery problem, with image builds, value files and secrets flowing through the same pipeline.
- Extra work: build custom container images that include client builds or module packages, and pin them to tags that match the chart and Synapse version in use.
- Extra work: separate configuration from the chart through values files and mounted secrets, so changes to branding or module settings do not require editing chart templates.
- Risks: a chart upgrade can overwrite or conflict with local overrides, and custom images can drift from the chart's expected Synapse version.
- Risks: running several workers and a Redis instance multiplies the number of places a module must be loaded and tested.
- Questions to answer: which chart and version are in use, where do custom images get built and stored, and who approves a change to values or images?
An air-gapped or restricted network changes how everything custom gets into the environment. Dependencies, client builds and module packages all need a controlled path in, and each import needs a review step.
- Extra work: mirror Python packages, container images, Helm charts and client build artifacts into the restricted network through an approved transfer process.
- Extra work: create a review step for each update, covering the source, the diff, the license and the tests run before import.
- Risks: a module that pulls a package at runtime or during build will fail silently or break after a transfer, so every dependency must be captured in advance.
- Risks: security patches arrive on the upstream schedule, so the transfer cycle can leave the environment behind for a period.
- Questions to answer: what transfer mechanism and approval chain does the network allow, how quickly must patches be applied, and who signs off on each import?
A deployment on Element Server Suite Pro or with Synapse Pro features changes which customization points are available. The licensed build may expose options or integrations that the open-source edition does not, and some of the customization plan depends on what it actually supports.
- Extra work: confirm in writing which customization points the licensed build exposes, such as module loading, client configuration and admin tooling, before designing any custom component.
- Extra work: check whether the licensed components (for example, MAS, LDAP or SCIM integration) replace or overlap with custom code already planned.
- Risks: building a custom module against an interface the licensed build does not support, or that changes between licensed releases.
- Risks: a custom plan that assumes open-source behavior may need rework once licensed components are in place.
- Questions to answer: which Element product and license tier is in use, what does the vendor document as supported for customization, and what happens to custom code when the licensed build is updated?
What you need to provide
Start with two named owners and the upgrade policy. Customization work goes faster when the client names one owner for Matrix administration (homeserver configuration, the admin API, user lifecycle) and one owner for branding decisions (Element colors, logos, feature visibility, and copy). The upgrade policy comes first in practice. It sets which Synapse and Element versions the custom code must support, so the team should confirm the target versions and how often the client accepts upgrades before any module or client fork is written. Synapse's upgrade notes warn that rolling back can be difficult because of schema changes, so this decision also affects how long old code stays in use.
Provide a staging homeserver and the delivery tooling. Staging should match production in Synapse version and database engine, since Synapse 1.143.0 and later require PostgreSQL 14 or newer and PostgreSQL is the recommended production database. Confirm that the team has access to source control and CI for the Element build, Synapse modules and bots, and that staging can run the same identity provider configuration as production. Ask whether staging is reachable from the client's network only, because test accounts and seeded rooms will sit there.
Supply branding and feature decisions in writing. Provide the logo files, color values, font rights, app names, and copy for each client platform in use. Include a written list of Element features to show or hide, with the reason for each choice, and the approver for changes to it. Verbal decisions tend to return during testing, so a single signed list reduces rework.
Inventory every bot, script and integration. List each existing bot, script, bridge, webhook and scheduled job, along with the upstream system it calls, the data it reads or writes, the account it runs under, and where its credentials are stored. Ask for the security requirements that apply to bots and Synapse modules, such as credential storage, token rotation, least-privilege accounts and review before deployment. Also record the identity setup in use (Synapse OIDC, SAML or CAS, or Matrix Authentication Service with an upstream provider), because each option changes how custom login and admin code must be written.
Name the release approver. Decide who signs off each release to production, who can approve a rollback, and how urgent security fixes to Synapse or modules are handled outside the normal cycle. Record these roles before work starts, so the first release does not stall on an unanswered question.
Frequently asked questions
Can our own team customize Matrix without an implementation partner?
Often yes for branding and simple bots, less so for module work and upgrade testing. Branding Element clients and building a simple bot are within reach of a team with Python and Matrix administration skills. Synapse pluggable modules depend on Synapse internals, and keeping them working means testing against each release. The deciding factors are the skills and time your team can commit to that ongoing work.
How long does a Matrix customization project take?
Duration depends on the number of clients, modules and bots in scope and on the target Synapse version. Each of these changes the amount of design, build and testing. Readiness also matters: access to test environments, your existing identity setup and clear branding requirements shorten the early phases. Your inputs are listed in the readiness section of this page. The schedule is fixed in the written scope before work starts, so ask for it with its assumptions listed.
What does a Matrix customization project cost, and what should a quote include?
The cost is built from discovery, design, build, testing, handover and later maintenance per upgrade. Discovery and design set the scope, build covers clients, modules and bots, testing covers functional and upgrade checks, and handover covers documentation and runbooks. Maintenance recurs with each Synapse release you adopt. A quote should list each phase, its deliverables, the environments used for testing, and which items are one-time and which recur. DeployOpen does not publish a price list.
Will our custom Matrix code break on the next Synapse release?
It can, and testing reduces that risk without removing it. Each custom module or bot is checked against a compatibility matrix that lists the Synapse, Python and PostgreSQL versions it supports. Upgrades are then rehearsed in a staging copy of your environment before production. Synapse's upgrade notes warn that database schema changes can make rollback difficult, so rehearsal matters more than a rollback plan. Ask how the matrix is maintained after handover.
Do we need Element Server Suite to customize Matrix?
It depends on the build and licence you run, so confirm this before the design is fixed. Element Server Suite comes as ESS Community, ESS Pro and ESS TI-Messenger, and ESS Pro includes Synapse Pro, MAS, LDAP and SCIM integration and auditing. Which edition and licence terms apply to your deployment determines which components you can change. Confirm these terms directly with Element.
Who owns the custom code and runbooks after handover?
Ownership is set by the terms in the written scope, so confirm them before work starts. The terms should state who holds the source repository, which licence applies to custom code, and whether runbooks and configuration documentation transfer to your team. Also ask how credentials and build artifacts are handed over, and whether a retainer covers later upgrades.
How DeployOpen delivers Matrix customization
DeployOpen scopes Matrix customization in writing before any build starts, then builds and tests branding, Synapse modules and bots against the homeserver version you run. Custom pieces are documented and handed over so your team can keep them working through upgrades.
How we scope
- Inventory the Element clients, Synapse modules, bots and integrations you want, with the owner and purpose of each
- Confirm the Synapse release, Python and PostgreSQL versions, and whether you run workers or a single process
- Agree in writing which branding, configuration and code changes are in and which are out of the fixed scope
- Identify where custom code touches admin APIs, authentication or federation settings that need extra review
- Ask for the scope to list the environments, test accounts and acceptance criteria used to close the work
How we build
- Build Element client branding and configuration as versioned files stored in a repository you control
- Develop Synapse pluggable modules against the pinned release, with tests that run on each upgrade candidate
- Build bots and integrations with scoped credentials, secrets stored outside code, and logging you can audit
- Test clients, modules and bots together on a staging homeserver that matches production configuration
- Keep custom code isolated from upstream files so routine homeserver releases do not overwrite changes
How we hand over
- Deliver a runbook covering each custom component, its dependencies, its configuration and its failure signs
- Document the upgrade test steps that confirm modules, bots and client builds still work after a Synapse release
- Transfer source repositories, build pipelines and access to your team with a walkthrough of each component
- Record which customizations depend on a specific Synapse or Element version so your team can plan changes
- Confirm with your team which parts you will maintain internally and which you want covered by a retainer
How we support
- Ongoing support, upgrades and testing of custom pieces are available as retainers, agreed separately from the build
- Retainer coverage can include re-running module and bot tests when new Synapse releases are planned for your environment
- Review the Synapse upgrade notes with your team before each planned release, including any schema change warnings
- Ask the retainer to name response expectations, the systems covered and who approves production changes
- Confirm how rollback would work, since Synapse upgrade notes warn that database schema changes can make rollback difficult

