Skip to content

Development journal

Practical notes from a small app studio.

Behind-the-scenes decisions from building, publishing, and operating mobile games and everyday apps.

RSS feed
React Native Analytics

Why an Expo app needs an analytics layer before adding Amplitude

18 min read

Written by: Jonathan Reis on

Build one analytics contract for an Expo app, keep Firebase and GA4 working, add Amplitude without rewriting product code, and gain independent rollout, failure isolation, and better product decisions.

OpenCode and Analytics

How to use the Google Analytics MCP in OpenCode to query GA4

13 min read

Written by: Jonathan Reis on

Configure Google's official Analytics MCP in OpenCode, authorize ADC access, and turn repeated GA4 questions into reproducible reports.

Monorepo architecture

How to keep canonical assets in a React Native monorepo

9 min read

Written by: Jonathan Reis on

A practical asset-library pattern for React Native apps, static sites, store exports, and shared audio without losing the editable original.

Expo native builds

How to create Android and iOS app icons in Expo without Android cropping them

9 min read

Written by: Jonathan Reis on

Use one editable icon source, an opaque iOS raster, and a transparent Android adaptive foreground so launcher masks do not crop your artwork.

Frontend Engineering

How to export a responsive Astro campaign as a PNG with a custom aspect ratio

9 min read

Written by: Jonathan Reis on

Build a browser-side PNG export button with an editable aspect ratio, a visible capture boundary, loaded fonts and images, and dimensions that match the downloaded file.

Product Marketing

How to launch an app on Reddit with organic engagement and honest measurement

10 min read

Written by: Jonathan Reis on

Prepare a community-specific app showcase with a native creative, compliant direct store links, readable QR codes, optional campaign metadata, and measurement that does not overclaim attribution.

Local AI

How to run FLUX 2, Z-Image and OmniSVG locally on Windows with ComfyUI

17 min read

Written by: Jonathan Reis on

Run FLUX 2 for raster work, Z-Image-Turbo for short readable text, and OmniSVG for native vectors on an AMD Windows PC with ComfyUI.

Remote access

How to use RustDesk over your local network with Direct IP access

9 min read

Written by: Jonathan Reis on

Configure RustDesk Direct IP access to control the existing desktop session over a LAN, verify the connection, and diagnose firewall or Wi-Fi isolation failures.

React Native Game Architecture

How to model board completion events for game feedback in React Native

9 min read

Written by: Jonathan Reis on

A practical event model for distinguishing a completed row, column, or block from the ninth correct placement of one digit, then routing both through sound and haptic feedback.

Game development

How to build a global line of independent logic puzzle games

11 min read

Written by: Jonathan Reis on

A practical strategy for launching Sudoku, Nonogram, Hashi, and other logic puzzles as independent products before connecting them in a shared collection.

Playwright and browser automation

How to connect Playwright MCP to Chrome through Remote Debugging

8 min read

Written by: Jonathan Reis on

A practical guide to enabling Chrome Remote Debugging, finding its dynamic CDP port, changing the Playwright MCP endpoint, and diagnosing 403 and ECONNREFUSED errors.

Product strategy

How to evaluate mobile app and game ideas before writing the MVP

10 min read

Written by: Jonathan Reis on

A practical method for comparing mobile product ideas using competitors, monetization, distribution, personal fit, and evidence instead of category size alone.

AI engineering

How to audit OpenCode AI gateways for model identity, silent fallbacks, and real cost

11 min read

Written by: Jonathan Reis on

A repeatable OpenCode workflow for checking whether an AI gateway routes the requested model, comparing billing with upstream prices, and testing image generation endpoints.

Expo and React Native iOS

How to run your first iOS build of an Expo app in a pnpm monorepo

14 min read

Written by: Jonathan Reis on

Step by step how I ran the first iOS build of an Expo app (Sudoku) that already built on Android, in a pnpm monorepo: prebuild, pod install, xcodebuild Release, simulator. Includes the three traps that block the build (babel, Hermes prebuilt, Firebase mock) and how to fix each one in versioned source files.

Game Development

How to embed Godot in a React Native app and measure the real cost

17 min read

Written by: Jonathan Reis on

An Expo POC hosts Godot in a native Android View, fixes the RN↔GDScript bridge, and replaces thousands of nodes with batched drawing; on iOS, the diagnosis shows why a build and bootstrap do not prove Simulator rendering.

VS Code and AI tooling

How to build a VS Code extension: I read the OpenCode one and wrote my own

10 min read

Written by: Jonathan Reis on

A practical tutorial on how to build a VS Code extension from scratch. I read the minified source of the official OpenCode extension, found the internal HTTP endpoint, and built one that sends any selection — including from unsaved files.

React Native Skia

Drawing an entire Sudoku board in one SkPicture (and why the declarative Canvas stuttered)

9 min read

Written by: Jonathan Reis on

Why the declarative Skia renderer with 81 React components per cell struggled on low-end devices, and how reimplementing the board with Skia.PictureRecorder + <Picture> removes the reconciler from the render hot path.

Astro and pnpm

When astro check says a dependency is missing but the real bug is a pnpm override

8 min read

Written by: Jonathan Reis on

How a global vscode-languageserver-protocol override broke @astrojs/check with ERR_PACKAGE_PATH_NOT_EXPORTED, and why removing the override fixed typechecking across Astro sites.

Studio operations

What changed when our institutional site started using analytics

8 min read

Written by: Jonathan Reis on

A practical note on adding GA4 and Cloudflare Web Analytics to a small studio site without turning legal pages, sitemap rules, and header/footer links into copy-paste drift.

Engineering process

Choosing mobile layout targets from production logs instead of device guesses

11 min read

Written by: Jonathan Reis on

How we used Loki user-agent logs, iPhone model usage data, and mobile screen-resolution stats to choose practical aspect-ratio targets for a React Native game layout.

Studio process

How we reorganized app documentation before it became unmaintainable

9 min read

Written by: Jonathan Reis on

A practical structure for app documentation: living plans, dated history, versioned release notes, product references, store copy, and release gates without turning one Markdown file into a junk drawer.

UX and product

Running a heuristic UX critique on my own app — and actually fixing what it found

9 min read

Written by: Jonathan Reis on

A solo developer walks through a Nielsen-based heuristic evaluation of a published React Native game, prioritizes the findings, and measures the score change after fixing them. Practical process for indie devs without a UX team.

Landing pages and conversion

Rebuilding the Daily Sudoku landing page after the Play Store launch

9 min read

Written by: Jonathan Reis on

The app was already published, but the website still talked like a pre-launch teaser. Here is what we changed — with AI assistants and an automated design critique — to turn it into a real conversion surface.

Astro and Cloudflare Pages

Blog dates off by one day: the timezone bug that affects every Astro site

6 min read

Written by: Jonathan Reis on

Every blog post on our Astro site showed the wrong date — one day earlier than the frontmatter value. The root cause was simple, but the complete fix touched frontmatter, formatting, sorting, and the content schema.

Expo Android release

Version, versionCode, and generated config: three numbers an Android release must align

8 min read

Written by: Jonathan Reis on

After nine Play uploads on versionName 0.1.0, lint overwriting production config, and ambiguous build script names, we documented SemVer rules, dev/prd commands, and why lint must not regenerate config.

React Native Analytics

How to validate Firebase DebugView events in a React Native release build

9 min read

Written by: Jonathan Reis on

Validate Firebase Analytics in a production React Native APK by combining local debug logs with the realtime response behind GA4 DebugView, even when its device counter says zero.

React Native Ads

AdMob UMP in React Native: privacy messages are not just console setup

9 min read

Written by: Jonathan Reis on

A practical release checklist for AdMob UMP in an Expo/React Native Android app, covering GDPR messages, US state privacy messages, app store linking, and the SDK gate before ads can request.

React Native

Your React Native confetti renders behind the cards: sibling order, zIndex, and elevation

8 min read

Written by: Jonathan Reis on

A win-screen celebration overlay fell behind the result cards and dropped too fast. The cause was React Native's sibling paint order, not a missing z-index. Here is why zIndex alone is not enough on Android and how we fixed both bugs.

Game Design

When helpful validation becomes a cheat: Sudoku notes that leaked the answer

7 min read

Written by: Jonathan Reis on

Our Sudoku blocked pencil marks that conflicted with the row, column, or box. It felt like a safety check. It was actually a free solver that told players which numbers were still possible. Here is the fix and the principle behind it.

React Native

A hidden TextInput can't capture a hardware keyboard on React Native's New Architecture

8 min read

Written by: Jonathan Reis on

We wanted physical-keyboard input in a React Native game on Android. The classic hidden TextInput trick failed under Fabric because showSoftInputOnFocus is ignored. adb proved it, and a config plugin fixed it for good.

React Native Skia

The rounded border that pushed every Sudoku digit off-center

8 min read

Written by: Jonathan Reis on

A border on an overflow-hidden container silently shifted our Skia board and un-centered every digit. Here is how screenshots, not eyeballs, found the real cause in a React Native game.

React Native tooling

Why __DEV__ is false in release builds, and how we gated dev tools by config instead

7 min read

Written by: Jonathan Reis on

A developer shortcut hidden behind __DEV__ disappeared exactly when we needed it in a release build. Here is why that happens in React Native and how we moved the gate to runtime config.

Design systems

Design tokens as one source of truth: giving a Sudoku app a real art direction

8 min read

Written by: Jonathan Reis on

How we gave a template-looking Sudoku a bold art direction by changing the theme tokens first, sharing them with our website, and staying inside a low-end performance budget.

React Native Haptics

Adding Expo haptics to a React Native game without making vibration a sound setting

7 min read

Written by: Jonathan Reis on

How Daily Sudoku added a persisted vibration toggle, reused gameplay feedback events, and kept Web bundling safe while using expo-haptics on native.

React Native Web

Playing the same WAV files in Expo Web and a React Native app

8 min read

Written by: Jonathan Reis on

How we reduced the gap between Web and app in an Expo/React Native game by replacing synthetic tones with bundled WAV assets and configurable audio logs.

React Native Testing

How to keep Playwright E2E useful when React Native Skia renders a canvas

9 min read

Written by: Jonathan Reis on

A field note on testing a React Native Skia canvas board with Playwright, replacing DOM-only selectors with a narrow test bridge, and keeping persistence deterministic.

Technical SEO

Google indexing checklist for Astro sites on Cloudflare Pages

9 min read

Written by: Jonathan Reis on

A field checklist for proving that Astro sites on Cloudflare Pages are crawlable, submitted in Search Console, and actually indexed by Google.

React Native Android

Disabling Android touch sounds in React Native without fighting Switch

6 min read

Written by: Jonathan Reis on

How one React Native sound setting ended up owning gameplay effects, Android tap feedback, and a double-toggle bug in a nested Switch.

React Native performance

Measuring perceived latency in React Native when frame metrics are not enough

7 min read

Written by: Jonathan Reis on

How we measured React Native response time from tap handler to state update and paint when frame stats did not explain what players felt.

React Native performance

Moving a React Native Sudoku board to Skia without deleting the old renderer

6 min read

Written by: Jonathan Reis on

How we tested a Skia Sudoku board behind config without deleting the React Native renderer, accessibility layer, or rollback path.

Expo Native Builds

When an Expo upgrade turns your splash screen into a white screen

8 min read

Written by: Jonathan Reis on

A practical field note on fixing a missing native splash after an Expo SDK upgrade by moving from the legacy splash block to the expo-splash-screen plugin.

Android monetization

How to validate a Google Play test purchase with RevenueCat

7 min read

Written by: Jonathan Reis on

A field checklist for tying one Google Play test purchase to RevenueCat credentials, the Play Console order, sandbox data, SDK identity, and Sentry.

Quality before beta

An honest checklist before expanding an Android internal test

7 min read

Written by: Jonathan Reis on

How to separate what a Google Play build has proven from SDK, billing, ads, and observability gaps before inviting more testers.

React Native on Google Play

Publishing an Expo/React Native app to Google Play with a local AAB

7 min read

Written by: Jonathan Reis on

How to build a local Expo/React Native AAB for Google Play and still validate signing, Firebase, Sentry, AdMob, RevenueCat, and Play delivery like a real release.

React Native release debugging

When versionCode changes but JavaScript does not: a React Native release trap

6 min read

Written by: Jonathan Reis on

A release bug where Google Play installed a new Android versionCode while the React Native JavaScript bundle still reported the old Sentry release.

Mobile monetization

When does RevenueCat make sense instead of direct Google Play Billing?

6 min read

Written by: Jonathan Reis on

A margin and operations breakdown for deciding whether an indie app should pay RevenueCat or own Google Play Billing support itself.

Google Play in Brazil

How to prepare a Google Play Console account for publishing an Android app in Brazil

6 min read

Written by: Jonathan Reis on

A practical order for getting developer identity, payments, public profile, account groups, signing keys, and legal pages ready before a first Google Play upload.