Background & experience

Skills · Where & for how long

Skills, by the work they come from.

These are the technologies I’ve used in my professional, freelance and personal work, placed on a timeline of when I used them. Every entry links to the work it came from: the case study, or my CV where there isn’t one.

Over time

– Present
20222023202420252026TotalENGAGEMENTSFRONTENDBACKEND & DATATESTING & DELIVERYTOOLINGUGV Nav · Aug 2026 – PresentUGV Nav3 moINTRALOT · Nov 2023 – PresentINTRALOT3 yrMalus Garden · Sep 2025 – Dec 2025Malus Garden4 moKIMATICA / POCITYF · Feb 2022 – Nov 2023KIMATICA / POCITYF1 yr 10 moCGWorks · Sep 2021 – Nov 2021CGWorks3 moJavaScript · CGWorks · Sep 2021 – Nov 2021JavaScript · KIMATICA / POCITYF · Feb 2022 – Nov 2023JavaScript · INTRALOT · Nov 2023 – PresentJavaScript · Malus Garden · Sep 2025 – Dec 2025JavaScript5 yrReact · CGWorks · Sep 2021 – Nov 2021React · KIMATICA / POCITYF · Feb 2022 – Nov 2023React · INTRALOT · Nov 2023 – PresentReact · Malus Garden · Sep 2025 – Dec 2025React5 yrRedux · INTRALOT · Nov 2023 – PresentRedux3 yrTailwind CSS · KIMATICA / POCITYF · Feb 2022 – Nov 2023Tailwind CSS · Malus Garden · Sep 2025 – Dec 2025Tailwind CSS2 yr 2 moNext.js · KIMATICA / POCITYF · Feb 2022 – Nov 2023Next.js1 yr 10 moSass · KIMATICA / POCITYF · Feb 2022 – Nov 2023Sass1 yr 10 moAccessibility · Malus Garden · Sep 2025 – Dec 2025Accessibility4 moi18next · Malus Garden · Sep 2025 – Dec 2025i18next4 moReact Router · Malus Garden · Sep 2025 – Dec 2025React Router4 moSEO · Malus Garden · Sep 2025 – Dec 2025SEO4 moTanStack Query · Malus Garden · Sep 2025 – Dec 2025TanStack Query4 moThree.js · CGWorks · Sep 2021 – Nov 2021Three.js3 moSQL · CGWorks · Sep 2021 – Nov 2021SQL · KIMATICA / POCITYF · Feb 2022 – Nov 2023SQL · INTRALOT · Nov 2023 – PresentSQL · Malus Garden · Sep 2025 – Dec 2025SQL5 yrJWT · KIMATICA / POCITYF · Feb 2022 – Nov 2023JWT · INTRALOT · Nov 2023 – PresentJWT · Malus Garden · Sep 2025 – Dec 2025JWT4 yr 9 moNode.js · KIMATICA / POCITYF · Feb 2022 – Nov 2023Node.js · INTRALOT · Nov 2023 – PresentNode.js · Malus Garden · Sep 2025 – Dec 2025Node.js4 yr 9 moObjection.js · KIMATICA / POCITYF · Feb 2022 – Nov 2023Objection.js · INTRALOT · Nov 2023 – PresentObjection.js4 yr 9 mohapi · INTRALOT · Nov 2023 – Presenthapi3 yrKnex · INTRALOT · Nov 2023 – PresentKnex3 yrMySQL · INTRALOT · Nov 2023 – PresentMySQL3 yrOAuth 2.0 · INTRALOT · Nov 2023 – PresentOAuth 2.0 · Malus Garden · Sep 2025 – Dec 2025OAuth 2.03 yrShipping APIs · INTRALOT · Nov 2023 – PresentShipping APIs · Malus Garden · Sep 2025 – Dec 2025Shipping APIs3 yrExpress · KIMATICA / POCITYF · Feb 2022 – Nov 2023Express · Malus Garden · Sep 2025 – Dec 2025Express2 yr 2 moPostgreSQL · KIMATICA / POCITYF · Feb 2022 – Nov 2023PostgreSQL · Malus Garden · Sep 2025 – Dec 2025PostgreSQL2 yr 2 moSSO integration · KIMATICA / POCITYF · Feb 2022 – Nov 2023SSO integration1 yr 10 moContent Security Policy · Malus Garden · Sep 2025 – Dec 2025Content Security Policy4 moStripe · Malus Garden · Sep 2025 – Dec 2025Stripe4 mowinston · Malus Garden · Sep 2025 – Dec 2025winston4 mozod · Malus Garden · Sep 2025 – Dec 2025zod4 moGraphQL · CGWorks · Sep 2021 – Nov 2021GraphQL3 moPython · UGV Nav · Aug 2026 – PresentPython3 moBamboo · INTRALOT · Nov 2023 – PresentBamboo3 yrJest · INTRALOT · Nov 2023 – PresentJest3 yrKibana · INTRALOT · Nov 2023 – PresentKibana3 yrKubernetes · INTRALOT · Nov 2023 – PresentKubernetes3 yrDocker · KIMATICA / POCITYF · Feb 2022 – Nov 2023Docker · Malus Garden · Sep 2025 – Dec 2025Docker2 yr 2 moaxe-core · Malus Garden · Sep 2025 – Dec 2025axe-core4 moDigitalOcean · Malus Garden · Sep 2025 – Dec 2025DigitalOcean4 moNginx · Malus Garden · Sep 2025 – Dec 2025Nginx4 moPM2 · Malus Garden · Sep 2025 – Dec 2025PM24 moReact Testing Library · Malus Garden · Sep 2025 – Dec 2025React Testing Library4 moGit · INTRALOT · Nov 2023 – PresentGit · Malus Garden · Sep 2025 – Dec 2025Git3 yrBash · Malus Garden · Sep 2025 – Dec 2025Bash4 moESLint & Prettier · Malus Garden · Sep 2025 – Dec 2025ESLint & Prettier4 mopnpm · Malus Garden · Sep 2025 – Dec 2025pnpm4 moVite · Malus Garden · Sep 2025 – Dec 2025Vite4 mo20222023202420252026ENGAGEMENTSFRONTENDBACKEND & DATATESTING & DELIVERYTOOLINGUGV Nav · Aug 2026 – PresentUGV Nav3 moINTRALOT · Nov 2023 – PresentINTRALOT3 yrMalus Garden · Sep 2025 – Dec 2025Malus Garden4 moKIMATICA / POCITYF · Feb 2022 – Nov 2023KIMATICA / POCITYF1 yr 10 moCGWorks · Sep 2021 – Nov 2021CGWorks3 moJavaScript · CGWorks · Sep 2021 – Nov 2021JavaScript · KIMATICA / POCITYF · Feb 2022 – Nov 2023JavaScript · INTRALOT · Nov 2023 – PresentJavaScript · Malus Garden · Sep 2025 – Dec 2025JavaScript5 yrReact · CGWorks · Sep 2021 – Nov 2021React · KIMATICA / POCITYF · Feb 2022 – Nov 2023React · INTRALOT · Nov 2023 – PresentReact · Malus Garden · Sep 2025 – Dec 2025React5 yrRedux · INTRALOT · Nov 2023 – PresentRedux3 yrTailwind CSS · KIMATICA / POCITYF · Feb 2022 – Nov 2023Tailwind CSS · Malus Garden · Sep 2025 – Dec 2025Tailwind CSS2 yr 2 moNext.js · KIMATICA / POCITYF · Feb 2022 – Nov 2023Next.js1 yr 10 moSass · KIMATICA / POCITYF · Feb 2022 – Nov 2023Sass1 yr 10 moAccessibility · Malus Garden · Sep 2025 – Dec 2025Accessibility4 moi18next · Malus Garden · Sep 2025 – Dec 2025i18next4 moReact Router · Malus Garden · Sep 2025 – Dec 2025React Router4 moSEO · Malus Garden · Sep 2025 – Dec 2025SEO4 moTanStack Query · Malus Garden · Sep 2025 – Dec 2025TanStack Query4 moThree.js · CGWorks · Sep 2021 – Nov 2021Three.js3 moSQL · CGWorks · Sep 2021 – Nov 2021SQL · KIMATICA / POCITYF · Feb 2022 – Nov 2023SQL · INTRALOT · Nov 2023 – PresentSQL · Malus Garden · Sep 2025 – Dec 2025SQL5 yrJWT · KIMATICA / POCITYF · Feb 2022 – Nov 2023JWT · INTRALOT · Nov 2023 – PresentJWT · Malus Garden · Sep 2025 – Dec 2025JWT4 yr 9 moNode.js · KIMATICA / POCITYF · Feb 2022 – Nov 2023Node.js · INTRALOT · Nov 2023 – PresentNode.js · Malus Garden · Sep 2025 – Dec 2025Node.js4 yr 9 moObjection.js · KIMATICA / POCITYF · Feb 2022 – Nov 2023Objection.js · INTRALOT · Nov 2023 – PresentObjection.js4 yr 9 mohapi · INTRALOT · Nov 2023 – Presenthapi3 yrKnex · INTRALOT · Nov 2023 – PresentKnex3 yrMySQL · INTRALOT · Nov 2023 – PresentMySQL3 yrOAuth 2.0 · INTRALOT · Nov 2023 – PresentOAuth 2.0 · Malus Garden · Sep 2025 – Dec 2025OAuth 2.03 yrShipping APIs · INTRALOT · Nov 2023 – PresentShipping APIs · Malus Garden · Sep 2025 – Dec 2025Shipping APIs3 yrExpress · KIMATICA / POCITYF · Feb 2022 – Nov 2023Express · Malus Garden · Sep 2025 – Dec 2025Express2 yr 2 moPostgreSQL · KIMATICA / POCITYF · Feb 2022 – Nov 2023PostgreSQL · Malus Garden · Sep 2025 – Dec 2025PostgreSQL2 yr 2 moSSO integration · KIMATICA / POCITYF · Feb 2022 – Nov 2023SSO integration1 yr 10 moContent Security Policy · Malus Garden · Sep 2025 – Dec 2025Content Security Policy4 moStripe · Malus Garden · Sep 2025 – Dec 2025Stripe4 mowinston · Malus Garden · Sep 2025 – Dec 2025winston4 mozod · Malus Garden · Sep 2025 – Dec 2025zod4 moGraphQL · CGWorks · Sep 2021 – Nov 2021GraphQL3 moPython · UGV Nav · Aug 2026 – PresentPython3 moBamboo · INTRALOT · Nov 2023 – PresentBamboo3 yrJest · INTRALOT · Nov 2023 – PresentJest3 yrKibana · INTRALOT · Nov 2023 – PresentKibana3 yrKubernetes · INTRALOT · Nov 2023 – PresentKubernetes3 yrDocker · KIMATICA / POCITYF · Feb 2022 – Nov 2023Docker · Malus Garden · Sep 2025 – Dec 2025Docker2 yr 2 moaxe-core · Malus Garden · Sep 2025 – Dec 2025axe-core4 moDigitalOcean · Malus Garden · Sep 2025 – Dec 2025DigitalOcean4 moNginx · Malus Garden · Sep 2025 – Dec 2025Nginx4 moPM2 · Malus Garden · Sep 2025 – Dec 2025PM24 moReact Testing Library · Malus Garden · Sep 2025 – Dec 2025React Testing Library4 moGit · INTRALOT · Nov 2023 – PresentGit · Malus Garden · Sep 2025 – Dec 2025Git3 yrBash · Malus Garden · Sep 2025 – Dec 2025Bash4 moESLint & Prettier · Malus Garden · Sep 2025 – Dec 2025ESLint & Prettier4 mopnpm · Malus Garden · Sep 2025 – Dec 2025pnpm4 moVite · Malus Garden · Sep 2025 – Dec 2025Vite4 mo
Each bar spans an engagement in which I used the technology; ongoing work runs to Oct 2026. Totals count calendar months, and overlapping engagements count once.

Frontend

Interfaces, styling & 3D

JavaScript

5 years

The language of my React and Node.js work at INTRALOT, KIMATICA / POCITYF and Malus Garden, and of my CGWorks work, from a framework-free museum tour to a React and Three.js configurator.

React

5 years

My main interface library: the operator platform’s core applications at INTRALOT, the Malus Garden shop and admin, the energy-community app at KIMATICA / POCITYF, and a 3D configurator at CGWorks.

Redux

3 years

State management in the React applications I build and extend at INTRALOT.

Tailwind CSS

2 years 2 months

Utility-first styling for the energy-community app at KIMATICA / POCITYF and both Malus Garden apps.

Next.js

1 year 10 months

The framework behind the energy-community app at KIMATICA / POCITYF, whose interface and navigation I also redesigned.

Sass

1 year 10 months

Styling for the energy-community app at KIMATICA / POCITYF.

Accessibility

4 months

Accessibility for the Malus Garden shop and admin, with a published statement of partial WCAG 2.2 AA conformance.

  • Malus Garden –

    Keyboard checks of the browse-to-checkout flow

i18next

4 months

Translation, with react-i18next, for the bilingual Malus Garden shop and admin.

React Router

4 months

Client-side routing for the two React apps at Malus Garden.

  • Malus Garden –

    Routing in the shop and the admin

SEO

4 months

Search and sharing metadata for the Malus Garden shop.

  • Malus Garden –

    JSON-LD structured data, a sitemap and Open Graph tags

TanStack Query

4 months

Server data, fetched and cached with React Query 5, in the Malus Garden shop and admin.

  • Malus Garden –

    Data fetching and caching in both apps

Three.js

3 months

3D rendering in the browser for my CGWorks work, on a virtual museum tour and a 3D configurator.

Backend & Data

APIs, databases & payments

SQL

5 years

Querying data to debug production issues at INTRALOT, the energy-community app’s database at KIMATICA / POCITYF, hand-written queries and migrations for Malus Garden, and fixes in the Eberus configurator at CGWorks.

JWT

4 years 9 months

Token-based authentication at INTRALOT, KIMATICA / POCITYF and Malus Garden, where the admin also has bcrypt-hashed passwords and rate-limited login.

Node.js

4 years 9 months

My server-side runtime: the service behind INTRALOT’s platform applications, the energy-community app’s APIs, and the Malus Garden API.

  • INTRALOT – Present

    The service orchestrating the platform’s microservices, and the shipping-document refactor

  • Malus Garden –

    The shop’s REST API, with Express

  • KIMATICA / POCITYF –

    Express REST APIs for the energy-community app

Objection.js

4 years 9 months

The ORM in INTRALOT’s Node.js services, and between the KIMATICA / POCITYF services and PostgreSQL.

hapi

3 years

A Node.js framework for services on INTRALOT’s operator platform.

Knex

3 years

SQL query building on INTRALOT’s operator platform; Objection.js builds on it.

MySQL

3 years

A database on INTRALOT’s operator platform.

OAuth 2.0

3 years

Authorization on INTRALOT’s operator platform, and the client-credentials flow the Malus Garden API uses to call BoxNow.

Shipping APIs

3 years

Carrier integrations at INTRALOT, and BoxNow parcel lockers for the Malus Garden shop.

  • INTRALOTCV (opens in a new tab) – Present

    UPS, USPS and SpeedEx carriers, in the ordering workflows

  • Malus Garden –

    BoxNow parcel lockers: the map widget at checkout, and a worker that sends parcels, with retries

Express

2 years 2 months

The web framework for the REST APIs at KIMATICA / POCITYF and Malus Garden.

PostgreSQL

2 years 2 months

The database for the energy-community app and the Malus Garden shop, where an order is marked paid in the same transaction that deducts its stock.

  • Malus Garden –

    Transactions, row locks and advisory locks, with additive migrations

  • KIMATICA / POCITYF –

    The energy-community app’s database

SSO integration

1 year 10 months

Single sign-on for the energy-community app at KIMATICA / POCITYF.

  • KIMATICA / POCITYF –

    Sign-in through an SSO service shared across the whole ecosystem, with JWT

Content Security Policy

4 months

A CSP for the Malus Garden apps, alongside helmet’s other security headers.

Stripe

4 months

Payments for the Malus Garden shop: an order is marked paid only when Stripe’s signed webhook arrives, and refunds carry an idempotency key so a retry can’t refund twice.

  • Malus Garden –

    Checkout Sessions, signed webhooks and refunds

winston

4 months

Logging for the Malus Garden API, with personal data masked.

zod

4 months

Request validation for the Malus Garden API.

GraphQL

3 months

Part of the Eberus 3D configurator stack I fixed bugs in at CGWorks.

Python

3 months

The language of the UGV Nav control stack: 134 tests passing, clean under mypy --strict and ruff.

  • UGV Nav – Present

    The rover’s control stack, in Python 3.12

Testing & Delivery

Tests, builds & releases

Bamboo

3 years

The build server behind INTRALOT’s releases.

Jest

3 years

Automated tests for my work at INTRALOT.

Kibana

3 years

Log search when I investigate a production issue at INTRALOT.

Kubernetes

3 years

The platform behind INTRALOT’s DEV and QA environments, which I release to.

Docker

2 years 2 months

Packaging and running the energy-community app at KIMATICA / POCITYF, and local development and database tests for Malus Garden.

  • Malus Garden –

    The local environment, and throwaway PostgreSQL containers for database tests

  • KIMATICA / POCITYF –

    Ran the app on private servers

axe-core

4 months

Automated accessibility audits of the Malus Garden shop and admin, which fail on a violation of any impact.

  • Malus Garden –

    0 axe violations against WCAG 2.2 A/AA rules on 20 pages, in Greek and English, at desktop and phone sizes

DigitalOcean

4 months

The cloud provider behind the Malus Garden shop, where production and staging each have their own database.

  • Malus Garden –

    Production and staging on one Ubuntu droplet

Nginx

4 months

The reverse proxy in front of the Malus Garden apps, redirecting to HTTPS and the bare domain.

  • Malus Garden –

    Reverse proxy, with Let’s Encrypt TLS

PM2

4 months

Process management for the Malus Garden API, which the release script restarts after backing up and migrating the database.

  • Malus Garden –

    Runs the API; the release script restarts it

React Testing Library

4 months

Component tests for the Malus Garden shop and admin.

  • Malus Garden –

    Component tests for both apps, in jsdom

Tooling

Builds & packages

Git

3 years

Version control and pull requests at INTRALOT and for Malus Garden.

Bash

4 months

The scripts that deploy and look after the Malus Garden server.

ESLint & Prettier

4 months

Code quality checks for the Malus Garden codebase.

pnpm

4 months

Package management for the Malus Garden monorepo, whose apps share UI, hooks, API-client and utility packages.

  • Malus Garden –

    A monorepo of the two apps and four shared packages

Vite

4 months

The build tool for the two React apps at Malus Garden.