Kraków / Remote

Marcin RapaczSenior Frontend Developer / AI Engineer

Frontend developer, six years on a single product. Since 2026, mostly applications with AI doing real work inside them.

I started with editors written in React, then came an e-commerce platform where one codebase served the stores of many brands. Since May I've been building the front end of a recruitment platform for a client in HR, and I own the quality of its candidate search — the kind that reads a described requirement and builds a ranking from it, instead of hunting for keywords in a CV.

More and more often I step outside the front end — I write the backend, and I take projects all the way to a running server.

LinkedIn ↗

Full experience and case studies are in the CV

of commercial experience, six of them at one product company, where I mostly delivered front-end projects and solutions
6.5 years

of commercial experience, six of them at one product company, where I mostly delivered front-end projects and solutions

chat and search over your own documents, shipped in StoryForge: the author asks about their book and the answer rests solely on its text, so the system suggests instead of making things up and never writes for them
RAG

chat and search over your own documents, shipped in StoryForge: the author asks about their book and the answer rests solely on its text, so the system suggests instead of making things up and never writes for them

of the front-end framework on live products, without pausing sales — even when the migration meant a full redesign
Migrations

of the front-end framework on live products, without pausing sales — even when the migration meant a full redesign

brings a finished book from a PDF into StoryForge: splits it into chapters, summarises them and pulls out characters, places and threads, so the author works on the text right away instead of retyping it
AI agent

brings a finished book from a PDF into StoryForge: splits it into chapters, summarises them and pulls out characters, places and threads, so the author works on the text right away instead of retyping it

01Selected work

HR-industry client (NDA) · since 05.2026

Recruitment platform

A recruiter types, in plain language, who they're looking for, and the system searches a base of a few thousand CVs. I built the entire new front end from scratch. The backend and the vector database were already running when I joined — I work on those, and I own the improvement of search quality. I started by building a way to measure it, because without one there was no telling whether the next version was any better than the last. The measurement showed that the same skill was stored in the database in over fifteen hundred different forms, so the result depended on how somebody happened to type it.

The logs the search had been collecting from the start later became a benchmark mirroring real traffic — and on it, in isolation from production, a second version of the search engine.

Fixing the data raised ordering agreement with the independent evaluation from 2% to 52%, and on the benchmark the rebuilt engine puts its list closer to the AI report in 22 postings against 2 (ordering agreement 70% vs 35%).

Read the case study →
  • Nuxt 4
  • TypeScript
  • Strapi
  • Gemini
  • Qdrant

own project · 2026

StoryForge

An app for people writing books — an editor with version history, a chat, style analysis, PDF import. It is not a generator that writes the book for the author: it supports work on the author's own text — ask a question, consult an idea, look for inspiration — and the system knows the book and answers from its content. I've run it from the first commit through to keeping it alive in production.

AI jobs go through a queue in the database, so a failure on the model's side never blocks saving text, and the credit returns to the user if the answer never starts. The style analysis deliberately uses no AI: it's an ordinary algorithm, so it costs nothing and gives the same answer every time. An existing book is imported by a separate agent (LangGraph) that detects chapters in code, and the model only gets a say when there are several conventions; instead of a progress bar the author reads what the agent is doing right now, and a failed import refunds the credits.

View demo ↗
  • Next.js 16
  • Strapi 5
  • FastAPI
  • LangGraph
  • Qdrant
  • RAG

internal tool for a client · second version · 2026

B2B lead sourcing

The second version of a B2B contact-sourcing tool for a client in HR, rewritten from scratch; the first was an agent with an LLM gate before sending, the second shifts the weight onto verifiable facts. Instead of buying contacts, the system builds its own base: it collects job postings with a history of bumps and paid promotions, pulls employer profiles, and a model with search access fills in what the posting lacks — company size, membership in a large organisation, phone, website. The model speaks once, in a typed answer that forbids guessing; whether a company is in the target is then decided by a plain rule on the facts.

No fact from the model reaches a person without confirmation from an independent source: first the company's website and the state register, because they are free, and only then paid Google Places with a double identity check. Every fact carries its origin and status, every model call has its cost recorded, and provider limits are enforced in code. At the end there is a list of companies with a confirmed number — a person makes the call. Over 300 offline tests, including a fake model.

About 1.3k companies in the base; 83% of in-target companies have a phone confirmed by an independent source (684 of 825).

See the case study →
  • Python
  • Pydantic AI
  • Gemini
  • FastAPI
  • PostgreSQL
  • Docker

company website · freelance commission · 09.2026

Folstar — mikroperforacja.pl

Company website of a family-run foil packaging manufacturer and sweets wholesaler near Kraków, rebuilt from scratch on Next.js 16 and React 19. I ran the commission directly with the client, no intermediaries: scope, copy and SEO, launch and maintenance — everything a small company needs from one person. Solutions sized to the client: content in code instead of the previous version's headless CMS, because with a dozen or so products that means fewer services to maintain and no dependency on an external vendor.

A product photo flies from its list card into the details window and a category photo from the home page into the landing hero (View Transitions); with reduced motion enabled the transitions disappear. Analytics and the Google map load only after consent, search engines see the business as LocalBusiness, and the deployment is a Docker image behind Traefik with a GitLab CI pipeline.

Visit the site ↗
  • Next.js 16
  • React 19
  • Tailwind 4
  • View Transitions
  • Docker / CI
Home page of mikroperforacja.pl: a hero with photos of sweets and foil rolls, a trust bar below

SaaS e-commerce platform · product team · 2020–2026

Printbox

Two roles over that time. I started with mobile redesigns of the photo-product editors, written in React. Then I moved to the team building the headless front end of the store platform on Shopware, from the first demo to production — and from there it was one continuous job: client rollouts ran in parallel with the architecture they stood on. One codebase served stores in several variants, from panel-only configuration to a full redesign.

Day to day that meant ordinary front-end work in a place where a mistake shows up in dozens of stores at once. Stripe and Adyen payments, InPost and GLS shipping in the checkout path, multiple languages, Core Web Vitals, memory leaks. And conversations: with the backend daily, with product before a task, and with new team members as an informal mentor on the architecture and the product.

I embedded the company's flagship editor, written in React, inside the stores — two routers that had to get along, working back and forward navigation, languages switched at runtime. A prerender of my own on Cloudflare Workers, for the client-side-rendered paths, replaced an external subscription.

The migration from Nuxt 2 to Nuxt 3 went out on a live product, one client at a time, without pausing sales. Along the way I co-designed the architecture the platform still runs on, and owned its implementation: a shared core, client customisations in separate layers and configuration read at runtime, so a change in the admin panel no longer requires rebuilding the application. The platform's most important client, a US retail chain, got a full redesign, SSO sign-in and a new payment gateway. Over those years a dozen-plus rollouts and redesigns passed through my hands, straight from Figma, and on the pilot for a global electronics manufacturer I built most of the front end.

One Docker image instead of a build per client: from 1.4 GB down to 55 MB, and updating every store takes minutes instead of hours, no matter how many there are.

  • React
  • Vue / Nuxt 2 and 3
  • Shopware
  • Turborepo
  • Redis
  • Stripe / Adyen
  • Cloudflare Workers

02How I work

Working on a team

On the e-commerce team we kept a full rhythm: standups, planning, demos, retros. Changes went through a ticket, a branch and a merge request, so someone else looked at every one before it was merged. Shared code with other frontend developers, conflicts to resolve, and day-to-day work with backend engineers, testers and customer success.

Owning the task

I take a task whole: from understanding the problem to a working release. Usually the goal is enough — the order of steps and the solutions along the way are mine to settle. Before that I pin down the details, and sometimes suggest a different approach that gets the same result for less.

Code written with AI

I write with Claude Code, and every feature goes through the same cycle: analysis and a plan, implementation in TDD with subagents for partial tasks, tests and benchmarks, deployment through CI/CD. The code that comes out of it I read and correct the way I would someone else's in review, before it reaches the repository. That pace produces more code than it used to, so all the more reason to record in commits and notes why something looks the way it does.

Tests where failure is silent

The worst bugs don't crash the app. They shift numbers or reorder results and look perfectly plausible. Those are the places I try to cover most densely with tests. The rest is checked too, in proportion to what can go wrong.

Design system and Figma

I start from colour, spacing and radius tokens kept in one place, and collect recurring layouts into shared components. Views go in pixel-perfect from Figma, and the first draft of a component I pull straight from the design through the Figma MCP server rather than retyping values by hand.

Performance isn't a separate phase

Core Web Vitals, bundle size and behaviour on a slow connection get checked alongside the feature I'm building. On the data side it's usually the same moves: collapse several queries into one, cache what doesn't change by the minute, and return only the fields the view actually renders.

03What I do

Frontend and backend

  • applications from an empty repository, and work in code I inherited
  • frontend architecture, component library, server-side rendering, performance
  • integrations: payments, shipping, CMS, sign-in, third-party APIs
  • the server layer under the front end: API, authorisation, middleware, job queues
  • Docker, a CI/CD pipeline and deployment to a server
  • Vue
  • Nuxt 4
  • React
  • Next.js
  • TypeScript
  • Tailwind
  • Node
  • Strapi
  • PostgreSQL
  • Docker

AI in the product

  • search by meaning, and chat that answers from your own documents
  • classification and extraction of data from unstructured text
  • suggestions and assistants built into the interface
  • measuring result quality and keeping an eye on query cost
  • working with models from different providers through their APIs
  • RAG
  • embeddings
  • Qdrant
  • Gemini
  • LLM-as-judge

AI agents

  • the model drives the run: it picks, judges and rejects, rather than just generating text
  • tools on its side: search, calls to external APIs, writes to the database
  • quality thresholds — no good result ends the step instead of passing something weak through
  • manual processes and integrations between systems never designed to talk to each other
  • job queues, retries, cost limits, and a person approving at the end
  • Python
  • FastAPI
  • Gemini
  • PostgreSQL
  • Docker

Contact

Kraków or remote. I work in Polish and in English. Write if you'd like to talk about working together, or to ask about any of the projects.

I also take on smaller projects.

I use Google Analytics to understand how this site is used and what to improve. Analytics scripts load only after you give consent. Privacy policy

Get in touch

Leave a message — I usually reply within one business day.