Skip to content

Maintenance & support

Maintain and Evolve Existing Clojure Systems

For companies with a Clojure codebase that still runs the business but no longer has the engineers who built it. The work is careful, incremental and documented.

transducta.core
(defn maintain [system]
  (-> system
      understand
      stabilize
      improve))

Highlights

  • Take over safely

    Onboarding starts with reading, running and documenting the system — not with a refactor.

  • Keep it current

    Clojure, JVM, library and infrastructure upgrades applied in small, reversible steps.

  • Keep it moving

    Bug fixes and new features continue to ship while stability improves.

The legacy Clojure situation

Clojure codebases age unusually well — immutable data and small functions do not rot the way a large object graph does. What ages badly is context. When the original engineers leave, what remains is a system nobody wants to touch: it works, it is critical, and every change feels risky.

The symptoms are consistent: dependencies years behind, a JVM version nobody has dared upgrade, tests that were once meaningful, a build that only worked on someone's laptop, and a small set of behaviours that only two people ever understood.

  • No current maintainer for a revenue-critical service
  • Dependencies and JVM versions that are years behind
  • A build or deploy process that nobody fully trusts
  • Undocumented behaviour discovered only during incidents
  • Feature requests parked because change feels unsafe

How a takeover actually proceeds

The first weeks are deliberately unglamorous. The system gets read, run locally or in a staging environment, and documented: entry points, data model, external dependencies, scheduled jobs, failure modes. Anything surprising is written down, because surprises are what cause incidents later.

Only then does change begin, and it begins with the safety net: getting the build reproducible, tests running in CI, and enough logging and metrics to see what production is doing. After that, upgrades and refactoring proceed in small pull requests that can be reviewed and reverted individually.

  • System and data-flow documentation
  • Reproducible build and dependency audit
  • Test coverage where change is most likely
  • Observability before refactoring
  • Incremental dependency and JVM upgrades
  • Ongoing feature work alongside stabilization

Why not rewrite

Rewrites are attractive because the existing system is hard to read and the new one is imaginary. But a production Clojure application encodes years of business rules, edge cases and regulatory quirks that exist nowhere else — not in the tickets, not in anyone's memory.

The honest recommendation is almost always to evolve: extract the parts that hurt, replace them behind stable interfaces, and let the system improve while it keeps earning. Where a rewrite genuinely is the right call, we will say so and scope the strangler-fig path rather than a big-bang cutover.

Frequently asked questions

Our Clojure codebase has no active maintainer. Can you take it on?
Usually yes. The first step is a short onboarding period to read the system, run it locally and document how it actually behaves before changing anything.
Do you offer ongoing support rather than project work?
Yes — a recurring monthly arrangement covering dependency upgrades, small features, bug fixes and availability when something breaks.
Will you recommend a rewrite?
Rarely. A working production system carries years of encoded business rules. Incremental evolution is almost always the lower-risk path.

Have a Clojure system with no maintainer?

Tell us what it does and what state it's in. The first conversation is technical and there's no obligation.