Skip to content
01Area of Expertise

Application and Systems Engineering

Chosen by fit, built to be maintained.

We build the software businesses run on - web platforms, backends and integrations, internal tools, mobile apps. Python, TypeScript, and Kotlin are the stacks we know best and work in every day. When the product calls for it, we reach for a wider toolkit that includes .NET and native desktop and mobile. If the system already exists, we work in your codebase rather than building a new one beside it. What doesn't change between stacks is the discipline - tests, contracts, review, documentation - and the rule that the language is chosen for the task, not the other way round.

At a glance
  • Python, TypeScript with Next.js, and Kotlin as the core - each with years of shipped work behind it - plus .NET, and native desktop and mobile toolkits when the estate or the product calls for them.
  • If your system is written in something not listed here, we work in it. We choose languages by fit and adjust to your codebase rather than bending your problem to our habits.
  • If a system has any way of communicating - an API, a file drop, a webhook, even the e-mails it sends - we can integrate it.
  • Architecture sized to the business: one well-structured backend first, services and queues when scale justifies them, and we'll say when it does.
  • Data entering the system checked in one place, on the server - whether it arrived from someone else's API, from a file, or from a person typing it in. Access done the same way: sign-in delegated to your identity provider over SAML or OpenID Connect, roles enforced on the server, key-based access for systems.
How we choose what fits

Before we talk stacks, we answer eight questions:

  1. 01

    What it is - a website, a web platform, an internal tool, a service that integrates other systems, a desktop application, a mobile app; each has a natural stack.

  2. 02

    What you already run - the codebase, the hosting, the team's languages; we build on that before proposing anything new.

  3. 03

    Who works in it - how many people, how often, and in what conditions; a screen for a warehouse hand wearing gloves is a different product from a panel for two analysts.

  4. 04

    Who maintains it - your developers, us, or nobody technical at all; that decides how much runtime and framework the product can carry.

  5. 05

    Integrations and compliance - payments, invoicing, identity, public registers, RODO; these shape the data model before the first screen exists.

  6. 06

    Performance and scale path - how many users, how much data, and how the system grows without a rewrite.

  7. 07

    Time to first release - how long there is until a first working version; that decides what gets built now and what waits for the next release.

  8. 08

    Long-term support - how mature the framework is, who owns it, and what happens if it's abandoned; this is where cross-platform frameworks get an honest look.

Every system we take on gets the same treatment regardless of language: a repository with tests and continuous integration, a written record of the decisions, and documentation the next developer can start from.

What we build

Web

  • Next.js - our default for the web: platforms with real business logic - commerce, course and training platforms, client portals, internal tools - and marketing sites where SEO, performance, and shipping speed matter. It renders what the backend decides, typed against a shared contract so the two can't drift apart unnoticed, and it pairs with any backend on this page.
  • Svelte or plain React - when a lighter front end fits the product or the team that will maintain it.
  • WordPress - where the site is that size, or where you're already committed to it and want it done properly.

A ready-made product is the right answer where your process looks like everyone else's - payroll is the clearest case. We build where the thing you do differently is exactly the thing a ready-made product cannot do. And where you buy one, the work we do is still there: making it talk to everything else you run.

Desktop

  • WinUI 3 with the Windows App SDK - the current way to build Windows applications; our default for new Windows desktop work.
  • WPF - for existing codebases and teams already invested in it; the ecosystem is mature and the code will keep running for years.
  • .NET MAUI - Windows and macOS from one .NET codebase when the organization is a .NET shop and a shared codebase is the priority.
  • C++ with CMake - one codebase for Windows, macOS, and Linux with hardware-level performance, when all three matter.
  • SwiftUI - for applications that live on the Mac.

A desktop application usually outlives the framework it was built on. We pick the toolkit for how long the app must run.

Mobile

  • Kotlin Multiplatform - shared business logic across Android and iOS when the product needs to ship fast on both and the team already speaks Kotlin.
  • Flutter or .NET MAUI - Flutter for UI-heavy apps that must look identical everywhere; MAUI when the organization is a .NET shop and wants one codebase.
  • Native - SwiftUI for iPhone and iPad; Kotlin for Android - for core systems where reliability, performance, and guaranteed OS support outweigh code sharing.

Cross-platform gets you to both stores fastest, but the app inherits the framework's release cycle and sits one layer away from the hardware. For business-critical apps that need the most from the device - performance, the security hardware, new OS features on day one - native is the choice.

Design and content, on every surface

  • Design systems across platforms - one set of tokens for color, type, and spacing applied to web, desktop, and mobile; measured contrast, real table markup, motion that respects reduced-motion settings.
  • Platform conventions - web components on the web; Fluent on Windows, Apple's Human Interface Guidelines on iPhone, iPad, and Mac, Material on Android - so an application feels at home on the device it runs on.
  • Content management by fit - a content management system when your team will edit content regularly, whether it lives inside the application or serves it headlessly; content kept as structured data in the codebase where nobody would edit it, so every price, claim, and label is reviewed before it goes live.
  • Motion and 3D where they earn it - Three.js and GSAP for products where interaction is the point.

Animation that delays the first meaningful screen costs more users than it impresses.

Backends and services

  • Python with Django - our most versatile tool: web backends for platforms with real business logic, small unattended systems, data tooling, machine-learning workloads with PyTorch. Fast to ship, easy to hand over.
  • Kotlin and Java on Spring Boot - our preferred way to build enterprise backends: integration-heavy services, long-lived systems, strong typing over messy external data. Kotlin by preference; Java where it's already in the estate - same platform and same tooling.
  • C# and .NET - C# backends and Azure-native services where the company already works in Microsoft tooling.
  • C and C++ - where performance or hardware proximity is the requirement; we'd rather use it where every microsecond counts than everywhere.

The language is chosen for the team that will maintain the system, not for the team you wish you had.

Integrations

  • Anything that communicates - APIs, webhooks, file drops, databases, message queues: payment and invoicing systems, ERP and accounting, identity providers, messaging and collaboration tools, automation platforms, public registers and government services.
  • Workarounds when there's no API - when a system's only output is the e-mail it sends, the file it exports, or the page it renders, that output becomes the integration point. If the data leaves the system in any form, it can be captured.
  • Legacy protocols - SOAP and XML services from another decade, handled without drama.

Every integration is a dependency on someone else's decisions. We build them so a change on the other side announces itself at once, instead of quietly corrupting data.

Architecture and scale

  • Modular monolith - one deployable backend split into clear modules - accounts, payments, catalog, admin - with boundaries enforced by tooling, so a module can be extracted into its own service when scale or team structure calls for it.
  • Microservices when justified - independent services with their own data and deployment pipelines, on the orchestration described under Cloud & Platform Engineering, when several teams or very different scaling profiles demand it.
  • One API for every client - REST or GraphQL serving web, desktop, and mobile, so the choice of client never dictates the backend.
  • Stateless front ends and caching - front-end tiers that hold no session state, and Redis in front of what's expensive, with cache lifetimes and invalidation designed rather than guessed.
  • Queues and events - Kafka or RabbitMQ when events must outlive the request or feed several consumers, at the scale that justifies them.
  • Warehouses and hosting - reporting and warehouses live under Data Platforms & Automation; scaling the hosts themselves under Cloud & Platform Engineering.

Microservices for a single team is a distributed monolith with a network bill.

Databases

  • PostgreSQL - the default: relational and transactional, and with its vector extension enough for semantic search at the scale most products reach.
  • SQL Server and Azure SQL - alongside .NET and Microsoft-centric estates, where the tooling and the team already live.
  • Document stores - MongoDB or similar when the data is genuinely document-shaped and the schema changes faster than migrations can follow.
  • Dedicated vector databases - when retrieval is the product and the index outgrows what PostgreSQL handles comfortably.

A document store is sometimes chosen to avoid designing the data's shape. The shape arrives anyway - by accident, and with nobody watching it.

Transactions, access, and audit

  • Payments and orders - prices and totals calculated on the server, purchases completed as atomic transactions, repeated requests handled once - so a double click or a retried callback never charges or books twice.
  • Access control - sign-in delegated to your identity provider over SAML or OpenID Connect; roles and permissions enforced on the server for every request; feature toggles that default to off when nothing says otherwise.
  • Audit trail - an append-only record of who changed what, when, and from where, on the records that matter: orders, entitlements, configuration.

A configuration mistake leaves you with the default. The default should be the safe state.

QA, deployment, and updates

  • Testing and contracts - regression tests for the flows that must never break; API contracts committed and checked so front end and backend can't drift apart.
  • CI/CD - every change reviewed, built, and tested automatically, then deployed through staged environments with a rehearsed rollback; on GitHub Actions, GitLab CI, or Azure DevOps - whichever your repositories already live in.
  • Updates and upgrades - dependencies pinned, audited, and updated on a schedule; framework upgrades rehearsed in a scratch environment before they touch production, with deprecations tracked rather than discovered. The wider patching and lifecycle practice lives under Reliability, Security & Lifecycle Management.
  • Moving the data you already have - out of spreadsheets, off paper, out of the old system; with an agreed rule for whatever does not reconcile, and without a stoppage that halts the business.
  • Taking over existing code - we audit, close the security gaps first, document what we found, and extend from there; a rewrite is the last option, not the first.

"Let's rebuild it from scratch" usually means "we haven't read it yet."

How we work

Every project follows the same sequence:

  1. 01

    Discovery - what the software must do, what already exists, and who will maintain it.

  2. 02

    Design - stack, architecture, and integrations agreed with you before we build; the decision written down with its alternatives. If we can see something will not hold up, we say so here, not after the release.

  3. 03

    Build - repository, tests, and continuous integration from the first commit; API contracts before screens. You talk directly to the engineers writing your system, with nobody in between, and we show you where the work stands against the schedule whenever you ask.

  4. 04

    Release - staged, with a rollback rehearsed, in windows that don't disrupt your operations.

  5. 05

    Hand over - the code in a repository you own, the documentation the next developer can start from, and administrative access.

  6. 06

    Support - we stay on an SLA for as long as it is needed: until the day your own IT takes the system over, or for years afterwards. The length is yours to set - we tie nobody to a term they did not choose.

What lands in your hands

At handover you get:

  • The code, in a repository you own
  • Tests and a CI/CD pipeline that runs and deploys them
  • The API contract, committed and checked automatically - where the system has one
  • Architecture decision records: what we chose, what we rejected, and why
  • Documentation and runbooks the next developer can pick up
  • Administrative access documented - nothing lives only in our heads
See this in practice