Work Blog About CV
Gothenburg, Sweden

Christian Toledo.
Full-stack engineer who ships and operates his own systems.

Close to seven years building production web and mobile apps, at product companies and as a consultant. React, React Native, Vue, Angular and .NET, for clients including PostNord, Nordic Wellness and Inera's 1177, the national healthcare platform millions of Swedes use. On my own time I build the same way: a ride-tracking app now in closed beta, running on two manufacturers' Bluetooth protocols I reverse-engineered myself, and a home lab of five systems I run and document like production.

Most recently a fullstack developer at Dear Friends and Nexer AB. Originally from Cuba, based in Gothenburg since 2011, and currently looking for my next team.

Selected work

Two things I built, ship, and keep running.

Not demos. One is an Android app and backend in closed beta with real users; the other is the platform it runs on. Both have real failure modes, and a written history of the decisions behind them: the protocol reverse-engineering, the physics regressions, and the infrastructure calls that went into each.

// mobile + backend

Cityroam

A ride computer for electric boards and scooters: an Android app and a self-hosted backend that talk to the hardware directly over Bluetooth. Two different manufacturers' proprietary protocols, both reverse-engineered and reimplemented from scratch. No vendor SDK, and no cloud account needed to ride.

In closed beta. The source is private, so the deep dives are the readable version: protocol notes, the physics model, and the decisions behind both.

  • Two vendor protocols, neither of them documented: the Tynee board's Tuya SDK was reverse-engineered and deleted outright, replaced by a from-scratch Kotlin GATT client verified byte-for-byte against a Python reference. The NAVEE scooter had no SDK to remove in the first place, so its encrypted challenge-response handshake had to be worked out from a real capture of the official app.
  • Physics fitted to your own rides: the backend fits per-mode rolling resistance, drag, and drivetrain efficiency by regression over real trip history, rather than trusting a manufacturer number or guessing linearly from battery percentage.
  • Offline first, by construction: every finished trip is written to the phone's own SQLite queue before any network call, so a ride exists the instant it ends whether or not the backend is reachable. Recording survives the app being backgrounded or killed outright.
  • Clean GPS from noisy hardware: raw phone GPS is road-snapped through a self-hosted OSRM instance and enriched with weather sampled across the whole route, so a ride that genuinely crosses from sun into rain shows that.
Expo / React NativeKotlinTypeScriptBluetooth LEFastAPISQLModelAlembicOSRMDocker
// platform

casa-verde

The Proxmox host and deploy pipeline that five separate systems run on. Not a pile of Docker containers, but a platform with infrastructure as code, encrypted secrets in git, drift detection against live state, and a written record of every real decision behind it.

Source is private, since it holds the encrypted secrets and the network layout for a house I live in. The deep dive covers the architecture and the decisions.

  • Push to main is the deploy: a self-hosted GitHub Actions runner applies the repo to the host and every container. Ansible for most stacks, GitOps for the ones where a webhook-speed redeploy earns its extra complexity. Chosen per stack, not dogmatically.
  • 82 written decision records: every non-trivial call has a documented reason, including the ones that turned out wrong and had to be reverted. That habit is the actual point of the project.
  • Actually monitored: a daily drift check runs the playbook against live state and alerts if anything was hand-edited outside the pipeline, plus automated backups and real failure alerting, not just “the container is still running.”
  • It hosts the other project: Cityroam's backend runs on this platform, deployed by the same pipeline. The two projects on this page aren't independent. One runs on the other.
Proxmox / LXCAnsibleDocker ComposeKomodo (GitOps)Cloudflare TunnelHome Assistant
Systems

Five systems, one platform.

casa-verde isn't one project. It's a Proxmox host and a deploy pipeline that five separate systems run on, each with its own stack, its own failure modes, and its own entries in the decision log.

// media pipeline

Media automation & streaming

A sixteen-container pipeline that finds, sorts, subtitles, and serves media, plus a photo library doing face recognition on the same integrated GPU that handles video transcoding.

  • Sonarr, Radarr, Lidarr, Prowlarr and Bazarr for acquisition and subtitles; Jellyfin and Navidrome for playback; Immich as a self-hosted Google Photos replacement
  • Jellyfin runs on the host rather than in a container specifically to get direct iGPU passthrough for hardware transcoding
  • A recurring Bazarr out-of-memory crash was root-caused rather than papered over with a restart policy
Docker ComposeJellyfinImmichIntel QSV / iGPU passthroughNavidromeSamba
How it works →
// home automation + local AI

Smart home & a local voice assistant

Home Assistant running the house, with a voice assistant whose speech recognition, speech synthesis, and language model all run on my own hardware, plus a deliberate split to a cloud model for everything that isn't about the house.

  • Whisper for speech-to-text, Piper for text-to-speech, and Ollama for the language model, all self-hosted and all originally proven viable on CPU alone before any GPU was bought
  • A hard privacy boundary: anything touching the home stays local by design; open-ended questions go to a separate cloud pipeline on a different wake word
  • Lights, blinds and motion sensors migrated onto Matter, while the dimmer switches stayed where they were, because moving them would have made things worse
Home AssistantOllamaWhisperPiperGroqMatterDocker Compose
How it works →
// game server ops

Game server

A Project Zomboid dedicated server for me and my friends, running about fifty mods with fully automated mod and update management.

  • The interesting constraint is that a mod update can break an existing save, so the automation has to be careful about when it applies one rather than just pulling latest
  • Provisioned and updated from the same Ansible repo as everything else, so there's no hand-configured server that only I know how to rebuild
AnsibleDockerProject Zomboidsystemd
How it works →
// network + access

Network, DNS & remote access

Local DNS with real hostnames and network-wide ad blocking, a reverse proxy in front of every service, and no open inbound ports at all. Remote access goes through a Cloudflare tunnel with authentication in front of it.

  • Nothing is port-forwarded. Every externally reachable service sits behind Cloudflare Tunnel with Cloudflare Access authenticating in front of it
  • AdGuard Home as the local resolver, giving every service a real .lan hostname and blocking ads network-wide
  • Self-hosted push notifications, so alerting doesn't depend on a third-party service staying free
AdGuard HomeNginx Proxy ManagerCloudflare TunnelCloudflare Accessntfy
How it works →
// platform + GitOps

Deploy platform & observability

Push to main is the deploy. Ansible for most stacks, GitOps for the ones where webhook-speed redeploys are worth an extra moving part, chosen per stack rather than dogmatically.

  • A self-hosted GitHub Actions runner applies the repo to the host and containers on every push; secrets are encrypted in git with SOPS and age
  • A daily drift check runs the whole playbook in check mode against live state and alerts if anything was hand-edited outside the pipeline
  • The architecture diagram on the repo's front page is regenerated by CI from an editable source, so it can't quietly go stale
AnsibleKomodoGitHub ActionsSOPS / ageProxmoxDocker
How it works →
Experience

Where the day job happens.

Nine years of employment across product companies and consultancies. As a consultant the employer is who paid, but the client is what the work actually was, so both are listed.

Front-End Developer Intern

Plejd AB · 2019 to 2020
  • Worked in a professional, 100,000+ line Angular.js/Vue.js codebase at a Swedish smart-home hardware company, building internal tools used by 50+ employees daily. My first real production codebase, alongside studying front-end development at Medieinstitutet
Clients & platforms
Plejd
Smart-home hardware

Swedish · listed company

Internal tools used daily by 50+ employees

Angular.jsVue.jsFigma

Front-End Developer

Nordic Retail Group (prev. Digital People) · Dec 2020 to Jan 2023
  • Sole frontend developer on Enginio, a Vue.js platform for building advertising campaigns and brand activations, from early startup through acquisition
  • Built a reusable Vue.js component library in Storybook, and owned frontend architecture, tooling, and CI/CD
  • Cut initial load time from 4.2s to 1.8s through lazy loading and bundle optimization
Clients & platforms
Enginio

B2B SaaS · advertising and brand activations

Sole frontend developer: architecture, component library, CI/CD

Vue.jsVuexSASSNode.jsExpressMongoDBCypressStorybookFigma

Fullstack Developer (Consultant)

Nexer AB · Feb 2023 to Mar 2025
  • Sole developer on a React Native app for Göteborgs Stadsmission, connecting surplus-food donors with people in need across Gothenburg
  • Built an internal React tool for PostNord used to plan postal delivery routes across Sweden
  • Contributed to Inera's 1177 public health platform (Optimizely + Angular) as part of a larger development team
  • Worked with backend developers on REST APIs and .NET integrations, and supported junior developers on React and TypeScript
Clients & platforms
1177 Vårdguiden
Public healthcare platform

National · millions of users

Angular frontend on Optimizely, as part of one of several teams

PostNord
Postal operator

Nordic · nationwide logistics

Internal React tool for planning delivery routes, in a larger team

Göteborgs Stadsmission
Non-profit, social services

Gothenburg

React Native app connecting food donors with people in need, as sole developer

ReactTypeScriptReact NativeOptimizely 11/12SASS.NET CoreC#SQL ServerAzure DevOps

Fullstack Developer (Consultant)

Dear Friends · Jan 2026 to Jun 2026
  • Built and shipped two React Native apps with Expo, one for Nordic Wellness and one for its premium brand Grand Fitness, each pulling live content and pricing from the Umbraco site behind it
  • Ran both projects end to end: testing, weekly test builds out to testers through TestFlight and Google Play Console, public releases, and managing the project itself
  • Built and maintained Umbraco (.NET) sites for several of the agency's clients, plus ongoing WordPress upkeep
Clients & platforms
Nordic Wellness
Gym chain

Largest in the Nordics · 300+ clubs

React Native app (Expo) and the Umbraco site behind it. Owned the pipeline from testing to public release

Grand Fitness
Premium gym brand

Part of Nordic Wellness

React Native app (Expo) and the Umbraco site behind it. Owned the pipeline from testing to public release

Fred's Food and Coffee
Hospitality

Gothenburg

Umbraco (.NET) site, built and maintained

IEMS, BabySlides, Doxa Bostad, Hagab
WordPress upkeep

Four agency clients

Maintenance, dependency updates, and content work

React NativeExpoUmbracoC# / .NETWordPressPHPTypeScript
Now · Looking for new opportunities

Client work delivered through Nexer AB and Dear Friends. Logos and names are trademarks of their respective owners, shown to identify projects I contributed to, not as an endorsement.

AI

How I actually work with AI.

Not a list of models I've heard of. This is what I run, what I decided and why, what it costs, and the one part of it I haven't solved yet.

Local, on my own hardware

Seven models pulled locally through Ollama (general, coding, and embedding), running on my own GPU. Before any of that, I checked whether the home voice assistant actually needed a GPU at all, and it didn't: speech-to-text runs about six times faster than real time on CPU alone. The research came before the purchase.

Cloud, chosen per job

Claude, OpenAI, Gemini, DeepSeek, z.AI and Groq, picked by task, cost, and latency rather than loyalty. There's one boundary I don't cross for convenience: anything touching my home stays on local models, by design. Open-ended questions go to a cloud pipeline on a separate wake word.

Agents as real tooling

Seven purpose-built subagents, deliberately split into read-only reviewers, test runners, and stack-specific implementers, plus agent instructions committed per repo. One of them drives a real Android build on an emulator and looks at the screenshots, rather than trusting that a step reported success.

In practice
45–57s → ~5–6s voice assistant latency, fixed by scoping the model and prompt correctly, not by buying hardware
768 candidates a fuzzy-matching regression I caused, diagnosed, and rolled back the same day
402M tokens · $18.90 routing bulk agent work to cheap models and reserving the expensive ones for what needs them
182 tasks · 47 delegated real multi-agent orchestration across code, architect, and review modes
7 local models run on my own GPU, after proving CPU-only inference was viable first
1 problem still open a local model that fabricates rather than admits uncertainty: documented, partly mitigated, not solved

The last figure is the one I'd want to be asked about. A local model that confidently invents an answer is a much more interesting problem than one that's simply slow, and I'd rather write that down than pretend the setup is finished.

What I run
Local
Ollama
Agents
Claude CodeRoo CodeClineCodexGemini CLI
Providers
AnthropicOpenAIDeepSeekz.AIGroqOpenRouter
Activity

Still building, most days.

Client work, my own products, and open source, across public and private repositories.

1,549 contributions in the last year
View GitHub profile ↗
CV

Want it on paper?

The full CV, in English or Swedish. The online version is the same content, but easier to read on a phone and always the most current.

Updated September 2026 · PDF · 3 pages

Want the fuller picture?

The About page covers the path from Cuba to Gothenburg and what I get up to outside of code, and the blog goes into detail on how Cityroam and casa-verde work. I'm looking for a team that cares about technical quality and ships real things. If that sounds like you, get in touch.