Skip to content
Available now · Full-time contract

Carlos Alberto Ortiz Ortiz

Senior Android Engineer

Kotlin Multiplatform & Jetpack Compose Specialist

Senior Android Engineer specialized in Kotlin Multiplatform and Compose migrations — I own features end-to-end and ship solo with AI-assisted workflows.

What I am hired for

  • Compose migrations without stopping the release train

    I moved 70% of the legacy UI screens in Elektra Go to Jetpack Compose while the app stayed in production, improving responsiveness and long-term maintainability.

  • Kotlin Multiplatform shared logic in production

    I led the KMP core layer connecting an Android app to mPOS hardware, sharing business logic with iOS and cutting development time by around 40%.

  • AI-assisted solo shipping

    I design agentic workflows and MCP integrations to ship products alone — from a published Roblox game to a native macOS interview-practice tool.

FocusAndroidKotlin MultiplatformAI-assisted development
  • 8+

    Years shipping Android

  • 1.5 yrs

    Independent contracting

  • 70%

    Legacy screens migrated to Compose

  • 40%

    Less dev time with KMP

  • 1–1.5s

    Faster app load time

  • 3,100+

    Organic visits on solo Roblox game

Extended profile

The version of my CV that does not fit on two pages

I am a Senior Android Engineer with 8+ years building and shipping production mobile applications for fintech, retail, and financial services. My core stack is Kotlin, Jetpack Compose, Clean Architecture, and Kotlin Multiplatform, and I have spent the last 1.5 years working as an independent full-time contractor for US-based clients.

Most of my career has been spent on code that other people already wrote. I have moved XML layouts to Jetpack Compose without stopping the release train, and I have rebuilt an app from zero in a parallel project when the existing one was no longer migratable. Both are legitimate answers; knowing which one you are facing is the skill. The work starts the same way either time: understanding why the old code exists before deciding what to do with it.

I also work the other direction: greenfield delivery. At Palo IT I built a fintech app end-to-end and led the Kotlin Multiplatform core layer that connected the app to mPOS hardware, sharing business logic across Android and iOS and cutting development time by around 40% compared to writing the same implementation twice.

AI-assisted development is part of how I work, not a side interest. I use agentic coding workflows and MCP integrations daily — Android Studio Gemini on client work, and multi-agent orchestration on my own projects, including a published Roblox game built solo from concept to release and a native macOS tool that streams my screen to an LLM for live code review while I practice technical interviews.

I am comfortable owning a feature end-to-end with minimal oversight: discovery, architecture, implementation, testing, release, and the follow-up when something breaks in production. I work well in remote-first teams, communicate in writing by default, and I would rather raise a blocker early than deliver a surprise late.

What I am hired for

Three things I do better than most Android engineers

Not a list of frameworks. These are the problems clients bring me when the app already exists and the roadmap cannot stop.

  • Compose migrations without stopping the release train

    I moved 70% of the legacy UI screens in Elektra Go to Jetpack Compose while the app stayed in production, improving responsiveness and long-term maintainability.

  • Kotlin Multiplatform shared logic in production

    I led the KMP core layer connecting an Android app to mPOS hardware, sharing business logic with iOS and cutting development time by around 40%.

  • AI-assisted solo shipping

    I design agentic workflows and MCP integrations to ship products alone — from a published Roblox game to a native macOS interview-practice tool.

  • Architecture rescue for legacy codebases

    MVP to MVVM, SQLite and Shared Preferences to Room, XML to Compose. I modernize legacy codebases, and I know when the honest answer is a rewrite in parallel instead of a migration.

  • End-to-end ownership with minimal oversight

    Discovery, architecture, implementation, testing, release, and production follow-up. I escalate blockers early instead of delivering surprises late.

Experience

Eight roles, and the reasoning behind each one

Expand any role for the context, the architecture decisions, and the measurable outcome.

  1. Senior Android Developer (Full-Time Contractor)

    Elektra USA

    Jul 2024 – Jan 2026

    Remote (US client)

    • Contract
    • Remote
    • Fintech
    • Remittances
    • Cross-border payments
    • 1–1.5s faster

      App load time

      Dependency cleanup, workload separation, restructured Hilt graph

    • 70%

      Legacy UI migrated to Compose

    • 2 per month

      Release cadence

      Two-week sprints, one release roughly every sprint and a half

    • Agency → direct contract

      Engagement

      Moved from staffing agency placement to the client's internal contracting entity

    • Modernized a cross-border remittance app by migrating legacy UI flows to Jetpack Compose and Navigation Compose.
    • Cut app load time by 1–1.5 seconds through dependency cleanup and restructured dependency injection.
    • Rebuilt the transaction core — the flow the product depends on — with proper architecture and no documentation to start from.
    • Architected new features with Clean Architecture and MVVM in a 40+ person distributed product organization.
    • Diagnosed and resolved a production signing-hash regression that broke Google service integrations.

    Stack

    • Kotlin
    • Jetpack Compose
    • Navigation Compose
    • Hilt
    • MVVM
    • Clean Architecture
    • Coroutines
    • Flow
    • Android Studio Gemini
    Read the full story

    Context

    Elektra Go is a fintech app for cross-border remittances: sending money from the US to Mexico, plus buying airtime, paying services, applying for a card, moving funds over ACH, and topping up the balance from stores in the US. The product is built for Mexican users living and working in the United States, which means every flow has to be simple enough to use after a long shift and trustworthy enough to move someone’s paycheck.

    The codebase was the real constraint. It had passed through several external consultancies, it was in-house development with no documentation, and it carried years of dead code, duplicated logic, and dependencies nobody could justify anymore. Shared flows ran across the entire app, so almost nothing was truly isolated — change one thing and you could break a payment path you had never opened.

    The team was large and distributed: 8 Android engineers (4 senior, 4 mid-level), 8 on iOS, around 8 on backend, about 5 in QA, plus tech leads and several product owners. I joined as an independent contractor through a US staffing agency, and later moved to a direct contract with the client’s internal contracting entity — retained on delivery quality rather than on the agency relationship.

    What I did

    As one of four senior Android engineers, I did code reviews, made architecture decisions, and mentored the mid-level engineers through pairing sessions.

    Stabilize before migrating. The first phase was subtraction: cleaning up dependencies, deleting code that was no longer used, and starting to centralize logic that had been copy-pasted across dozens of screens. Migrating a feature on top of a codebase you do not understand just moves the mess to a new syntax.

    Migrate the UI. Once the ground was stable, we moved screens to Jetpack Compose. We started with classic Navigation and eventually migrated to Navigation Compose. For the Compose work itself I used AI-assisted tooling to accelerate UI prototyping and cut boilerplate.

    Rebuild the core. The remittance and transaction flow was officially untouchable — it was the product. Eventually it had to be rebuilt anyway, with proper architecture and practices. Getting there took sustained pressure from the senior engineers, because the honest cost was the time required to understand the basecode before touching it. Without documentation, and with shared flows crossing the whole app, reading and tracing dependencies was the work.

    Fix production. Details in the section below — the app lost access to some Google services after a signing hash changed.

    Architecture and decisions

    Hilt over Koin. We chose Hilt because it is the Android standard and the team already knew it. Koin was technically viable and would have been faster to adopt in places, but adding a third-party dependency meant going through approval with the product owners. The standard option was the one we could justify without a fight, and consistency across 8 Android engineers mattered more than a small ergonomic win.

    Order of migration by risk, not by visibility. The first screens to move to Compose were the low-impact “side features” — the ones with the fewest dependencies on the rest of the app. That gave us real migration experience on code that could not take down a payment, and it built the pattern before we applied it to anything critical.

    Everything is a shared flow until proven otherwise. The founding assumption became: this flow is referenced somewhere you have not looked. It changed how we planned every refactor and why dependency cleanup had to come before feature migration.

    The signing hash incident

    A change in how CI/CD generated the build changed the hash the app was signed with. The app kept working for most users, but integrations with some Google services broke because the registered certificate hash no longer matched.

    Diagnosing it meant working backwards from the symptom: the build was green, the APK installed, but the service handshake failed. I traced it to the signing configuration change, then had to recover the correct hash — which no longer matched anything we had on file.

    The fix required generating a temporary production build purely to extract the new hash from it, updating the value in the Google developer console, and verifying the affected integrations. The lesson was that signing identity is production configuration, not build detail, and it deserves the same change control as a database migration.

    Impact

    • App load time reduced by 1–1.5 seconds.
    • 70% of the legacy UI running on Jetpack Compose.
    • Transaction core rebuilt on a maintainable architecture, with the senior team aligned on why it was worth the cost.
    • Release cadence of 2 per month held while the migration was in flight.
    • A production incident resolved without a user-facing outage.

    What I would do differently

    I would use AI to map the basecode from day one. Understanding an undocumented codebase is exactly the kind of reading-heavy, high-volume work that agents are good at, and it is the best use of AI I have found when starting on an existing project: feed it the unfamiliar modules, ask it to trace shared flows and dependencies, and get a map in hours instead of days. We lost real time doing that manually, and it would have shortened the path to the core rebuild.

  2. Android Developer

    Palo IT · client: Femsa

    Aug 2022 – Dec 2023

    Mexico (remote)

    • Full-time
    • Remote
    • Fintech
    • Payments
    • Point of sale
    • ~40% reduction

      Development time on shared logic

      Estimated from the sprints saved after choosing KMP, versus maintaining two native cores

    • Android + iOS

      Platforms on one core

      iOS consumed the shared module through CocoaPods

    • 4 + 4

      Team on the shared layer

    • Built a card payment acceptance app for debit and credit cards, integrating physical mPOS hardware.
    • Owned the full charge flow: device connection, transaction, and PDF ticket generation.
    • Led the Kotlin Multiplatform core sharing networking, request building, transaction rules, and device state.
    • Deliberately kept permissions and UI native on each platform instead of forcing them into the shared layer.

    Stack

    • Kotlin
    • Kotlin Multiplatform
    • Ktor Client
    • Kotlinx Serialization
    • Koin
    • Jetpack Compose
    • Navigation
    • StateFlow
    • GraphQL
    • CocoaPods
    • mPOS SDK
    Read the full story

    Context

    Femsa was opening a new business line and needed to start accepting card payments. The app was the pilot: an Android and iOS application for charging debit and credit cards, connected to a physical mPOS device. From the app you paired with the mPOS, ran the entire charge flow, and generated the receipt as a PDF ticket.

    That made the hardware the hardest part of the product. The mPOS is not a peripheral you can treat casually — it is a certified payment device with its own protocol, its own permission requirements on each platform, and manufacturer instructions that have to be followed exactly. The devices also carried keys that required custom firmware updates, which meant device provisioning was part of the work, not a setup step someone else handled.

    We were a Palo IT team assigned to Femsa: 4 Android and 4 iOS engineers, with the same team covering backend.

    What I did

    I worked on the Android application and led the shared core in Kotlin Multiplatform. The app itself followed the standard modern Android setup — Jetpack Compose, Navigation, StateFlow — with GraphQL for data.

    The KMP core owned the parts of the system that must behave identically on both platforms:

    • Networking and request building
    • Request validations
    • Transaction rules
    • Device state

    Architecture and decisions

    What we shared, and what we refused to share. UI and permissions stayed native on each platform. This was deliberate: permissions and UI are where the platforms genuinely differ, and forcing them into a shared layer would have traded a real abstraction problem for a fake one. The rule was that only logic which must agree across platforms belongs in the core — everything else stays where it can use the platform properly.

    iOS consumed the module through CocoaPods. The iOS team implemented the integration and consumed the shared code as a dependency in their app, which kept ownership on their side without forking the logic.

    GraphQL was inherited, not chosen. Femsa already had a GraphQL-based prototype, so keeping it was a constraint rather than a decision. Working inside an existing protocol choice is a normal part of contract work; the job is to make it predictable, not to relitigate it.

    The ~40% figure, honestly

    The 40% is an estimate, not an instrumented measurement. It comes from the number of sprints we did not need after deciding to use KMP, compared against the original estimate for building the same capability natively on each platform.

    The business case was straightforward: two cores means two implementations to maintain, more engineers across two teams, and a guaranteed drift between them as each platform evolves on its own schedule. One core removes the drift entirely and the second platform becomes a consumer instead of a parallel project.

    Testing the shared layer

    The most valuable tests were the ones that pinned cross-platform behavior. A large part of the request body was constructed inside the shared module, so the key assertion was that both platforms produce an identical request for the same transaction. If Android and iOS generate the same payload from the same inputs, the shared layer is doing its job.

    What I would do differently

    Understand the scope of KMP earlier and more precisely. It is easy to see the “shared code” win and start moving things into the module that should have stayed native. Drawing that boundary properly — logic yes, UI and permissions no — is the decision that determines whether a multiplatform core stays maintainable or becomes a second framework nobody wants to touch.

    Impact

    • Around 40% less development time on shared logic versus two native implementations.
    • One core consumed by Android and iOS instead of two parallel codebases.
    • Card payment acceptance shipped end-to-end: connection, transaction, and PDF ticket.
    • A reusable integration pattern for future platforms.
  3. Android Developer

    Covalto

    Mar 2022 – Jul 2022

    Mexico (remote)

    • Full-time
    • Remote
    • Fintech
    • Lending
    • Credit
    • PDF + PNG

      Documented attachment limits

      With file-size validation inside the credit application flow

    • Worked on the credit application flow where entrepreneurs signed documents and attached supporting files.
    • Delivered the documentation attachment flow: PDF and PNG uploads with file-size limits.
    • Unit-tested with JUnit, MockK, and Robolectric and validated REST integrations with Insomnia and Postman.

    Stack

    • Kotlin
    • MVVM
    • MVI (Uniflow)
    • JUnit
    • MockK
    • Robolectric
    • REST
    Read the full story

    Context

    Covalto is a Mexican fintech that issued loans and credits to entrepreneurs across sectors like agriculture. The app I worked on was the front door of that business: the place where a credit application happened. Applicants signed documents digitally and attached whatever the application required — the paperwork that used to be a trip to an office.

    The team was around 15 people across Android, iOS, QA, and product, distributed across Mexico, Colombia, Switzerland, and Turkey. Remote-first Scrum, working across time zones.

    What I did

    I delivered features on the application flow with MVVM and Uniflow, the MVI implementation the project already used. The piece I owned most directly was the documentation attachment flow: uploading PDF and PNG files with a size limit, which sounds trivial and is not. File handling in a financial application means validation, failure states, and making sure a user who uploaded the wrong document is not stuck.

    Alongside feature work I wrote unit tests with JUnit, MockK, and Robolectric, and validated REST integrations with Insomnia and Postman before handing them to QA.

    A note on the architecture

    Uniflow was already in the codebase when I joined; the reasoning behind adopting it predated me, and I worked within the pattern rather than relitigating it. What I can speak to honestly is what it bought us in practice: a single ordered state per screen, which matters in a multi-step application where a wrong intermediate state is a real defect rather than a visual glitch.

    Why it ended

    The company was acquired by another bank and went through a full restructuring, which ended the engagement. Short contract work has that in it — the engineering outlives the org chart, and the features shipped are still in the product.

    Impact

    • Credit application features delivered on a two-week Scrum cadence in a distributed team.
    • A documentation attachment flow with explicit file-type and size validation.
    • REST integrations verified before QA, reducing regression churn.
  4. Android Lead

    Invex

    May 2021 – Feb 2022

    Mexico

    • Full-time
    • On-site
    • Banking
    • Financial Services
    • 3–5 devs

      Team size

    • Parallel project

      Rewrite approach

      Rebuilt from zero alongside the production app instead of migrating it

    • Led the full rewrite of the internal app into a new Kotlin, MVVM, and Jetpack project.
    • Ran the rewrite in parallel with the production version to avoid a maintenance freeze.
    • Planned deliverables per release and mentored and delegated to new engineers on the team.

    Stack

    • Kotlin
    • MVVM
    • Room
    • Navigation
    • LiveData
    • Android Jetpack
    • Code review standards
    Read the full story

    Context

    After three years building internal banking applications at Invex, I moved into a lead role. The trigger was the state of the codebase I already knew well: the delivery app I had built was still on MVP, and years of accumulated practice had turned it into code that was increasingly expensive to maintain. It needed more than a refactor.

    What I did

    I proposed the rewrite and took the initiative to do it in parallel with the production version rather than declaring a freeze on the existing app. That was the decision that made the project survivable: the business kept receiving fixes and small changes on the old app while the new one was built next to it.

    Moving into the lead role changed what my work actually was:

    • Architecture decisions were mine now, not something I implemented from someone else’s design.
    • Planning — breaking the rewrite into timeboxes and deliverables tied to each release, so progress was visible instead of a long silent march.
    • Mentoring and delegation — new engineers joining the team needed the patterns explained and the work distributed, which is the part of senior work that does not appear on a commit log.

    We settled on Kotlin, MVVM, and Jetpack components (Room, Navigation, LiveData) as the standard, and standardised code reviews so the new project would not drift back toward what it replaced.

    Architecture and decisions

    Rewrite, not migration. The MVP codebase was not migratable in practice — poor practices and spaghetti logic meant a mechanical port would have carried the same problems into new syntax. Rewriting from zero was more expensive upfront and cheaper over the following years.

    Parallel delivery. The alternative was a freeze on the production app, which would have meant pausing the business to improve it. Running both tracks simultaneously was more work for the team but kept the product alive, and it gave us a real benchmark: the new code had to be demonstrably easier to change than what it replaced.

    Adoption was not the hard part. Standardising on Kotlin and MVVM met little resistance, because the alternative was maintaining the app we were all already tired of. When the status quo is painful enough, the standard argues for itself.

    Impact

    • Internal app rebuilt from zero on Kotlin, MVVM, Room, Navigation, and LiveData.
    • Production app continued to receive changes throughout the rewrite.
    • 3–5 engineers mentored and given ownership of defined pieces of the work.
    • Code review standards that outlasted the project.
  5. Android Developer

    Invex

    Aug 2018 – May 2021

    Mexico

    • Full-time
    • On-site
    • Banking
    • Financial Services
    • 100+

      Operators using the app

      Across the country, delivering cards outside bank branches

    • Built an internal credit card delivery app used by 100+ operators nationwide.
    • Implemented biometric authentication to confirm the card was handed to the right person and prevent identity fraud.
    • Automated a process that previously required the customer to visit a branch.

    Stack

    • Java
    • Kotlin
    • MVP
    • SQLite
    • Shared Preferences
    • Fingerprint API
    • Material Design
    Read the full story

    Context

    Invex is a Mexican bank. The problem the app solved was physical: to receive a credit card, the customer had to go to a branch and do the paperwork in person. The app changed that flow entirely — a courier arrives wherever the customer is, delivers the card, and collects the documents needed to activate it on the spot. More than 100 operators used it across the country.

    That last part is what made the app interesting. It was not a form with a database behind it; it was a banking instrument running in the field, on devices and networks you do not control, in the hands of people who are not technical, standing in front of a customer.

    What I did

    I built the delivery application, including the biometric authentication module that verified the card was being handed to the person they claimed to be. That check is the whole point of the flow in a fraud sense: without it, “delivered to the right person” is just an assertion by whoever is holding the phone.

    I worked in Java and MVP initially, with SQLite and Shared Preferences for persistence, and Material Design for the interface. Over the following years that foundation became the thing we replaced — I go into that in the lead role.

    Architecture and decisions

    The security decision that mattered most was making biometrics a required step rather than an optional convenience. It is easy to add fingerprint as a login shortcut and call it security. Here it was identity evidence for a specific handover, and the flow had to be built so that skipping it was not possible.

    The other lesson was about the environment. Software that runs in the field has to assume bad connectivity, old devices, and interrupted flows. Persistence that survives an app being killed mid-delivery is not a nice-to-have; if the record disappears, the physical card is already gone.

    Impact

    • 100+ operators running the delivery flow nationwide.
    • Customer no longer needs a branch visit to receive and activate a card.
    • Biometric verification reduced identity-fraud exposure at handover.
    • A three-year base of domain knowledge that directly informed the later rewrite.
  6. Mobile Developer

    iGenter

    Sep 2015 – Apr 2018

    Mexico

    • Full-time
    • On-site
    • Software Agency
    • Mobile
    • HR Tech
    • Built an internal employee app with check-in/check-out, vacation requests, schedules, and payslips.
    • Delivered a two-platform job board app in Android and iOS for candidates to browse and apply to open roles.
    • Managed the full release lifecycle through Google Play and resolved production incidents across device profiles.

    Stack

    • Android
    • Java
    • iOS
    • SQLite
    • Volley
    • Google Maps API
    • Facebook SDK
    Read the full story

    Context

    iGenter is a staffing agency, and this is where my professional mobile career started. Agency work means building for two audiences at once: the company’s own operations, and the people the company places.

    What I built

    An internal app for agency employees. It handled check-in and check-out when employees arrived at or left their work area, vacation requests, shift schedules, and payslips. This is back-office software in the best sense — it replaced paperwork and a phone call for the people who needed an answer about their own schedule.

    A job board, in Android and iOS. Candidates registered, browsed the positions the agency had open, and applied from the app. Two platforms, one product, which is where I learned what actually differs between them — and how much of the difference is platform convention rather than real constraint.

    What I did

    I developed across both platforms and owned the full lifecycle: build, Play Store submission, and the production incidents that followed. I integrated Google Maps API and GPS services, REST APIs with Volley, SQLite persistence, token-based session management, and Facebook SDK for social login.

    What I took from it

    Shipping through a store teaches things development never does. Device fragmentation, review processes, and crash reports from phones you have never seen are the real conditions, and they push you toward defensive networking and explicit session handling.

    Session management in particular is where I learned to reason about auth state properly — expiry, refresh, and what the user sees when their session dies mid-application.

    Impact

    • Two shipped products: an internal employee app and a two-platform job board.
    • Full release ownership on Android and iOS.
    • Production incidents diagnosed across a wide range of devices and OS versions.
  7. Digital Marketing and Web Operations

    Pirelli

    2014 – 2015

    Mexico

    • Full-time
    • On-site
    • Manufacturing
    • Digital Marketing
    • Supported B2B platform implementation inside the digital marketing area.
    • Coordinated digital campaigns, email execution, and vendor communication.
    • Built and maintained internal registration and notification workflows using Google Apps tooling.

    Stack

    • Google Apps
    • Web Operations
    • Campaign Tooling
    Read the full story

    Context

    Before I moved fully into software engineering, I worked in digital marketing and web operations at Pirelli. It is not Android work, but it is where I learned how a business actually consumes the software it asks for.

    What I did

    I supported the implementation of a B2B platform inside the digital marketing area, coordinated digital campaigns and email execution, and handled communication with external vendors. I also built internal registration and notification workflows using Google Apps tooling — small automation that replaced manual coordination.

    Why it matters

    Working on the business side first changed how I build software. I have seen what happens when a platform is delivered without understanding the people who operate it, and I have been the person doing the manual work a system was supposed to remove.

    That perspective shows up in how I write features: I care about the operator, not just the user in the design mock. It is also why I gravitate toward automation — removing manual work is the part of software I find genuinely satisfying.

    Impact

    • B2B platform implementation supported end-to-end.
    • Internal workflows automated with lightweight Google Apps tooling.
    • A business-side perspective that shaped my later engineering decisions.
  8. Digital Marketing and Web Specialist

    WSIBSNS / Monkey Solutions

    2011 – 2014

    Mexico

    • Full-time
    • On-site
    • Digital Agency
    • Web
    • Developed early digital delivery skills across SEO, PPC, SEM, and campaign planning.
    • Worked on CMS-based web implementations with WordPress and Magento.
    • Maintained direct client communication, translating business needs into online solutions.

    Stack

    • WordPress
    • Magento
    • SEO
    • PPC
    • SEM
    Read the full story

    Context

    This is the earliest stage of my career: a digital agency where I worked across web implementation and marketing for a range of clients, before specializing in mobile.

    What I did

    I worked across SEO, PPC, and SEM, planned campaigns, and built and maintained websites on WordPress and Magento. I was also the direct point of contact with clients, which meant translating a vague business goal into something that could actually be built.

    Why it matters

    Two things from this period stuck with me.

    The first is CMS and theme work, which is where I learned to read someone else’s markup and CSS and change it without breaking it — the same skill that later became legacy Android migration.

    The second is client communication. Explaining trade-offs to a non-technical stakeholder, in writing, without over-promising, is a skill that most engineers are never taught. I learned it early and I still use it in every contract engagement.

    Impact

    • Delivered CMS-based web implementations with direct client ownership.
    • Built early expertise in search and paid acquisition.
    • Learned to translate business requirements into shipped work.
Solo projects

What I build when nobody is paying me

Shipped solo, end-to-end, as a proof that agentic workflows and native engineering can coexist outside a client engagement.

  • Mi Cumple

    Featured

    A Roblox game with minigames and a social space for birthday parties, shipped solo with an MCP-connected agent pipeline

    2024 – 2026
    • Solo
    • Published
    • Solo developer, designer, and publisher
    • 3,100+

      Visits

      Roblox algorithm discovery, a small ad campaign, and a friend-invite reward feature

    • ~2 months

      Time to ship with AI

      After 12+ months of slow part-time progress building it by hand

    • 1

      Team size

      Concept, assets, scripting, and publishing handled solo

    • Designed and shipped a complete Roblox game end-to-end as a solo developer.
    • Built the lobby and minigame systems by hand before introducing AI to the pipeline.
    • Ran two specialized agents over MCP — one generating models through Blender, one writing and importing Luau.
    • Wrote agent rules that stopped concurrent agents from mixing changes and corrupting the project.

    Built with

    • Roblox Studio
    • Luau
    • Blender
    • MCP
    • AI agents
    • Sub-agents
    • agents.md
    Read the full story

    What it is

    Mi Cumple is a Roblox game with two halves. The first is a set of minigames — musical chairs, a donut-eating contest, and others. The second is a social space where players celebrate birthday parties: cut a cake, put on music, wear party hats, and hang out with whoever is in the server.

    It is live and playable, and it reached 3,100+ visits through Roblox’s algorithm, a small ad campaign I ran, and a reward feature for inviting friends.

    How I built it, in the order it actually happened

    By hand first. I started conventionally: writing the Luau scripts myself, learning the Roblox Studio IDE, and building the lobby system and the minigame system from scratch. This part matters — I did not learn the platform through an agent. I built the architecture I would later ask agents to respect.

    Then the agent pipeline. I connected Roblox Studio and Blender to my agents over MCP and split the work in two:

    • One agent generates models through Blender and returns them to the project.
    • One agent writes the Luau scripts, imports the generated models, and creates the features around them.

    The flow per feature. The plan is drafted by the agent and refined with me before anything is built. We hold the architecture and the separation of functions steady so features do not start bleeding into each other. The Blender agent produces the models, the Luau agent writes the code, the agent runs its own tests, and then I play the build as a real player. If it holds up, it ships.

    That last step is not optional. An agent can confirm the code does what it was asked. It cannot tell me whether the game is fun.

    The failure that taught me the whole lesson

    At the start there were no rules. Without an agents.md defining boundaries, the agents started breaking things and mixing unrelated changes together, and I was reverting by hand trying to work out what had been lost. That is the worst failure mode with agentic development: not a wrong answer, but diffuse answers that touch everything at once.

    Writing the rules fixed it. Once the scope, the ownership of each area, and the architecture constraints were written down and enforced, the flow became natural — and the speed became real instead of chaotic.

    Scope is the thing that nearly broke it

    There is a second, subtler failure I only saw in hindsight. The publishing rules for the platform can change quickly, and once AI made development fast, I lost the target. I kept adding features because adding them was cheap, and that widened the game past what the rules allowed, which eventually cost discoverability.

    The estimate of the work did not change. My discipline about what to build did.

    The numbers, honestly

    I spent more than 12 months making slow, part-time progress by hand. Once the agent pipeline was in place with proper rules, the remaining work shipped in about two months. The speed came from the pipeline — but it only worked because the architecture and the constraints were already mine.

    What it proves

    • Agentic pipelines are an engineering problem, not a prompting problem. Interfaces, rules, ownership, and verification decide the outcome.
    • Real product delivery is now viable solo for things that used to need a team.
    • Shipping to a live platform with real players is the only honest test of whether an AI workflow is useful.
  • AI Code Reviewer

    Featured

    A macOS menu bar app that sends a screenshot of my code to an LLM and streams back live feedback

    2026
    • Solo
    • Published
    • Solo developer
    • 4+

      Models tested

      Kimi, GLM, DeepSeek, MiMo — chosen for latency and feedback quality

    • Image compression + timeouts

      Latency work

      Compressed captures and tuned connection timeouts to keep feedback usable

    • Built a native macOS menu bar app in Swift that captures the screen on demand.
    • Sends the capture and a configurable prompt through the OpenCode API to an LLM.
    • Externalizes model and prompt into a JSON file so the whole behaviour is tunable without a rebuild.

    Built with

    • Swift
    • macOS
    • Menu bar
    • Screen capture
    • OpenCode API
    • LLM streaming
    • JSON configuration
    Read the full story

    What it is

    A macOS menu bar app. I trigger a screenshot from a keyboard shortcut or by clicking the icon, and the app sends that capture plus a prompt to a configured LLM through the OpenCode API. The feedback comes back and I read it while the code is still on screen.

    Why I built it

    Interview practice is a solo activity, which means you are the only person checking your own work. I wanted the experience of someone looking over my shoulder — flagging a suboptimal approach, pointing out complexity I had not considered, and asking the question I was avoiding.

    I built it in Swift for two reasons: screen capture needs a real native app to work properly, and I wanted a reason to work outside the Android ecosystem.

    How it works

    • Capture is manual and deliberate. There is no background recording. I decide when the code is worth reviewing, which also keeps the cost and the noise down.
    • Behaviour is configuration, not code. The model and the prompt live in a JSON file. Swapping models or rewriting the instructions does not require a rebuild.
    • Transport through the OpenCode API. I use the OpenCode terminal for development and its API to send the capture and prompt and receive the result.

    The two problems that actually mattered

    Latency. Feedback that arrives after you have moved on is worthless, so the pipeline is tuned for continuous flow rather than one-shot analysis. I tested several models — Kimi, GLM, DeepSeek, MiMo — shortened the connection timeout, and compressed the image before sending, because the payload size was a direct tax on how fast the answer came back.

    Signal versus noise. This was the harder one. A model that comments on everything trains you to ignore it, and then the tool is worse than nothing. The fix was the same lesson that shows up in every agentic system I have built: tighter rules and a much more specific prompt. Constraining what the model is allowed to care about is what makes its output worth reading.

    Do I use it

    Yes. Interview practice, and also while working through courses — I take a capture of whatever I just wrote and read the critique. It is the most direct demonstration I have that I can build a native Apple-platform app, wire an LLM into a real-time pipeline, and ship the result as something I actually rely on.

  • This Landing Page

    An extended CV built as a static Astro site with typed content, an agent-driven content pipeline, and a glass Material 3 design system

    2026
    • Solo
    • In progress
    • Solo developer and designer
    • 100% typed

      Content model

      Every content file validated with Zod — a bad entry fails the build

    • Static

      Pages

      Landing plus a print-optimised extended CV export

    • Replaced a React SPA with a statically generated Astro site for performance and SEO.
    • Modeled the entire CV as typed content collections validated at build time with Zod.
    • Set up project-level AI agents and skills so the content interview, the build, and the design review are reproducible.

    Built with

    • Astro
    • TypeScript
    • Tailwind CSS
    • Zod
    • Content Collections
    • Material 3
    • Glassmorphism
    • opencode agents
    Read the full story

    What it is

    The site you are reading. It is the extended version of my CV: the same career, told with the context, decisions, and reasoning that do not fit on two pages — which means it is also a writing project as much as a build.

    Why it exists

    A PDF CV compresses everything into bullets. That works for a recruiter scanning for keywords and fails for anyone who wants to know how I actually think about architecture, legacy code, or working inside an existing team. So I built the version I would want to read: structured, honest about the reasoning behind decisions, and deep enough that a technical hiring manager can judge the engineering instead of the vocabulary.

    How it is built

    Static generation with Astro, replacing a Vite + React SPA. Plain files behind nginx, no runtime, no server to maintain.

    Content as data. Roles and solo projects are content collections with Zod schemas; the rest is typed JSON. The site cannot silently render an empty section because someone mistyped a field — a malformed entry fails the build.

    A design system, not a stylesheet. Material 3 tokens (color roles, elevation, type scale, motion) over a glassmorphism surface language, with light and dark themes driven by CSS custom properties and a single glass recipe. A dedicated skill documents the rules so the system stays consistent as sections are added.

    An agent workflow around the content. The interesting part for me was building the process, not just the page: project-level agents for content drafting, frontend implementation, and design review; skills that encode the copywriting rules and the design constraints; and a screenshot pipeline so layout changes are verified against actual renders rather than assumed. It is the same discipline that made the Roblox project work, applied to a static site.

    Why it is listed here

    Because the workflow is the point. Building a site is not remarkable; building one with a reproducible content pipeline, enforced schemas, documented design tokens, and agent roles that keep the quality bar steady is the thing I would want a client to see.

    Verification

    astro check and astro build are the definition of done, and every layout change is checked by capturing the rendered sections and reading them back.

How I work

AI-assisted development, applied like engineering

Agentic tooling only pays off when the work is scoped, the interfaces are real, and the output is verified. This is the workflow I run.

  1. 01Rules before agents

    Every project starts with an agents.md that defines scope, ownership, and architecture constraints. Without it, agents mix unrelated changes together and you spend your time reverting diffs by hand trying to work out what was lost.

  2. 02Scope discipline, because speed is now cheap

    When adding a feature costs almost nothing, it is easy to lose the target. I define what the product is — and what it is not — before the agent pipeline starts, so velocity does not turn into drift.

  3. 03Real interfaces through MCP

    Agents are connected to the actual tools — Roblox Studio, Blender, the local editor — so they operate against real state instead of hallucinating an API that does not exist.

  4. 04Sub-agents with one job each

    A main agent coordinates; specialized sub-agents execute. One generates models in Blender, one writes and imports the Luau. Narrow scope and independent verification per agent.

  5. 05Map unfamiliar code before changing it

    On undocumented legacy codebases I use agents to trace shared flows and dependencies and produce a map in hours instead of days. It is the highest-value use of AI I have found on an existing project.

  6. 06The agent tests; a human verifies

    Agent output goes through the same bar as any contribution: it compiles, it runs, it passes tests, and it reads like something a team could maintain. Then I verify the thing that actually matters — play the game as a real player, read the rendered page.

  7. 07A human keeps the judgment

    I decide the architecture, the trade-offs, and what ships. AI accelerates work I already understand; it does not replace the reasoning. An agent can confirm the code does what it was asked — it cannot tell me whether the product is good.

Technical skills

Tools, and how deep I actually go with them

Honest levels. I mark what I am exploring as exploring.

  • Languages

    Day-to-day languages and how deep I go with each.

    • KotlinExpert
    • JavaAdvanced
    • SQLAdvanced
    • SwiftWorking
    • TypeScriptWorking
  • Android & UI

    Modern Android UI and the legacy surface I migrate from.

    • Jetpack ComposeExpert
    • Material DesignExpert
    • NavigationExpert
    • XML ViewsAdvanced
    • FragmentsAdvanced
  • Architecture & State

    Patterns I use to make apps testable and predictable.

    • Clean ArchitectureExpert
    • MVVMExpert
    • MVPAdvanced
    • MVI (Uniflow)Advanced
    • Coroutines & FlowExpert
    • StateFlowExpert
    • LiveDataAdvanced
  • Kotlin Multiplatform

    Shared business logic between Android and iOS.

    • Kotlin Multiplatform (KMP)Advanced
    • Ktor ClientAdvanced
    • Kotlinx SerializationAdvanced
    • Koin (shared layer)Advanced
  • Dependency Injection

    • HiltExpert
    • DaggerAdvanced
    • KoinAdvanced
  • Networking & Data

    • GraphQLAdvanced
    • RetrofitExpert
    • REST APIsExpert
    • RoomExpert
    • MoshiAdvanced
    • GsonAdvanced
    • SQLiteAdvanced
    • FirebaseAdvanced
    • Firebase CrashlyticsAdvanced
    • SupabaseAdvanced
    • VolleyWorking
  • Testing & Tooling

    • JUnitAdvanced
    • MockKAdvanced
    • RobolectricAdvanced
    • EspressoProficient
    • GitExpert
    • CircleCIAdvanced
    • GradleAdvanced
  • AI-Assisted Development

    How I multiply my own output as a solo developer.

    • Agentic coding workflowsAdvanced
    • MCP integrationsAdvanced
    • Multi-agent orchestrationAdvanced
    • Android Studio GeminiAdvanced
    • OpenCode / Claude / CodexAdvanced
  • Additional Mobile Exposure

    • XcodeWorking
    • CocoaPodsWorking
    • Google Maps APIAdvanced
    • GPS servicesAdvanced
    • Facebook SDKProficient
Beyond Android

Where I am expanding next

Android is my expertise, not my ceiling. These are the platforms I am deliberately moving into, and what I have already shipped in each.

  • In production

    Kotlin Multiplatform

    Shared business logic between Android and iOS, shipped to production inside a fintech app rather than kept as a proof of concept.

    • Led the KMP core layer connecting the app to mPOS hardware at Palo IT / Femsa
    • Around 40% less development time versus duplicating the logic natively per platform
    • Ktor Client, Kotlinx Serialization, and Koin inside the shared layer
  • In production

    AI & agent engineering

    Agentic workflows and MCP integrations used to ship complete products solo, not as demos.

    • Mi Cumple: Roblox game shipped solo with agents connected to Roblox Studio and Blender
    • AI Code Reviewer: native macOS tool streaming screen capture to an LLM in real time
    • Multi-agent orchestration with narrow, verifiable sub-agent scopes
  • Actively building

    Apple platforms (Swift / macOS)

    Native Apple-platform engineering, starting from a tool I genuinely needed rather than a tutorial project.

    • AI Code Reviewer written in Swift as a native macOS application
    • Working knowledge of Xcode and CocoaPods
    • Screen capture and real-time streaming pipelines
  • Actively building

    Web frontend (Astro / TypeScript)

    Modern web delivery to complement mobile: static generation, typed content, and design systems.

    • Rebuilt this site as a statically generated Astro + TypeScript project
    • Content modelled as typed collections validated with Zod at build time
    • Early career CMS work with WordPress and Magento
  • Up next

    Backend & APIs

    Deep client-side integration work is already there; server-side services are the deliberate next step.

    • Extensive integration with GraphQL and REST APIs in production apps
    • Designed shared networking layers for multiplatform consumption
    • Next: Node.js on the server side, plus Ktor and Kotlin where the stack calls for it
  • Up next

    Compose Multiplatform

    Extending Compose expertise from Android into shared UI across platforms.

    • Jetpack Compose is my primary UI toolkit and where my deepest UI experience sits
    • Comfortable with the state and lifecycle model Compose Multiplatform builds on
    • Natural extension of the KMP work already shipped to production
  • In production

    Product business & infrastructure

    Running a 3D printing business end-to-end since May 2026: the infrastructure, the storefront, the payment flow, and the logistics behind every order.

    • Configured and run the VPS that hosts the business
    • Built the storefront on WooCommerce
    • Purchase flow with Stripe and MercadoLibre payment gateways
    • Print, fulfilment, and shipping logistics handled directly
Education & continuous learning

Formal background, applied practice

  1. Technical High School Diploma in Computer Science

    Universidad de Negocios ISEC · Mexico City, Mexico

    Technical high school in computer science. Where the programming foundation started, years before any professional mobile work.

    • Computer Science
    • Programming Fundamentals

    2007 – 2010

  2. Ingeniería en Sistemas Computacionales

    Degree not conferred

    Universidad Victoria · Mexico

    Coursework completed up to roughly 95%. The degree was never formally conferred — I went to work instead, and the professional record above is what I bring instead of the title.

    • Software Engineering
    • Databases
    • Networks

    2010 – 2015

  3. Licenciatura en Sistemas Administrativos

    Universidad del Valle de México · Mexico

    Completed while already working professionally in mobile development, which is where the business-side perspective on software comes from.

    • Information Systems
    • Business Administration

    2015 – 2018

  4. Claude Certified Developer — Foundations

    In progress

    Anthropic

    Currently studying for the certification, formalising the agentic workflows I already run in practice.

    • AI agents
    • Anthropic API
    • Prompt engineering

    2026 — in progress

  5. Applied AI & Agentic Engineering

    In progress

    Self-directed, continuous

    Agentic coding workflows, MCP integrations, and multi-agent orchestration applied to shipped products rather than tutorials.

    • AI agents
    • MCP
    • Automation

    2024 – Present

  6. Swift & Apple Platform Development

    In progress

    Self-directed, continuous

    Native macOS tooling in Swift, extending beyond Android and into the Apple ecosystem.

    • Swift
    • macOS
    • Xcode

    2025 – Present

Working together

How I engage, and what you can expect

Remote-first, contract-oriented, and structured so you always know where things stand.

Availability

Available now

Starting immediately

Time zone overlap

CST / UTC-6

Overlaps with US and EU business hours, available until 6:00 PM CST

Work mode

Remote

Remote-first, distributed teams, written-first communication

How I bill

Hourly · Monthly retainer

No published rates. We scope the work first, then I give you a number.

Contract setup

Direct contract · Through a staffing agency

I have been engaged both ways and I am comfortable with either.

Engagement models

  • Full-time contract
  • Part-time
  • Project-based
  • Short sprints

No minimum hours — short sprints and part-time blocks are both fine.

How I operate

  1. 01

    Owner, not ticket-taker

    I take a problem and come back with a working feature, not a list of questions. I raise blockers early, in writing, before they become delays.

  2. 02

    Migration or rewrite — decided honestly, and early

    Sometimes the right move is migrating a live app screen by screen; sometimes the codebase is not migratable and a parallel rewrite is the cheaper answer. Deciding that early, and honestly, is half the work.

  3. 03

    Ship, then measure

    Performance and reliability work is only real if it moves a number users can feel — like the 1–1.5 seconds cut from Elektra Go startup.

  4. 04

    Written-first communication

    Remote-first teams work when context is written down. I default to documented decisions over meetings that nobody can reference later.

FAQ

Questions I get from clients

What kind of engagements do you take?

Remote full-time contracts are my main focus, but I also take part-time work, fixed-scope projects, and short sprints when the fit is right. I am available now and can start immediately.

Engagement

Can you work with teams in the US and Europe?

Yes. I am based in Mexico City on CST / UTC-6 and I overlap with both US and EU business hours, staying available until 6:00 PM CST. I have worked remote-first with multicultural Scrum teams for most of my career.

Engagement

Do you only work on greenfield apps, or also existing codebases?

Both, but existing codebases are where I add the most value. I have migrated legacy UI to Jetpack Compose in a live app while the product kept shipping, and I have rebuilt an internal banking app from zero in a parallel project because the MVP codebase was not migratable in practice. Deciding which of those you are facing — honestly, and early — is most of the work.

Technical

What is your Kotlin Multiplatform experience?

At Palo IT I led the KMP core layer that connected a fintech app to mPOS hardware, sharing business logic across Android and iOS. That cut development time by around 40% versus building the same implementation twice natively. I have also worked with Ktor Client, Kotlinx Serialization, and Koin in the shared layer.

Technical

How do you use AI in client work?

I use AI to accelerate work I already understand: Compose UI prototyping, boilerplate reduction, refactor planning, and test scaffolding. I only use tooling approved by the client, and I never send proprietary source code to external models without explicit approval. AI output is reviewed the same way I review any other contribution.

AI

How do you approach a migration without a full rewrite?

I start by mapping what the legacy code actually does and why, not just what it looks like. Then I introduce the new standard alongside the old one — a screen, a module, or a use case at a time — with tests around the seams so the product keeps shipping. That is how 70% of the Elektra Go UI moved to Compose without a freeze.

Technical

What does your testing approach look like?

I default to unit tests on business logic and view models with JUnit and MockK, Robolectric where the Android framework is involved, and Espresso for critical UI flows. I care more about tests that catch real regressions than about a coverage number.

Technical

Contact

Available now for remote Android contract work

Full-time contract is my focus, but I am open to part-time, project-based work, and short sprints. I reply to every serious inquiry.

Status

Available now

Response time

Within 24 hours

Time zone

Mexico City, Mexico · CST / UTC-6

Engagements

Full-time contract · Part-time · Project-based · Short sprints

How I bill

Hourly · Monthly retainer

Contract setup

Direct contract · Through a staffing agency

Reach me through

Email or LinkedIn are both fine. If you have a role or a project in mind, send the scope and I will tell you honestly whether I am the right fit.

Audience

  • US and EU companies hiring through staffing agencies
  • Startups that need a senior Android owner without a full mobile team
  • Product teams that need to migrate legacy Android code to Compose, KMP, or Clean Architecture