DEV Community

Cover image for I built an open-source Cloudflare manager for Android with React Native
Taqin
Taqin

Posted on

I built an open-source Cloudflare manager for Android with React Native

The Cloudflare dashboard is great on a laptop and painful on a phone. So I built CloudFlare Mobile: an unofficial, open-source Android client that talks straight to the Cloudflare API with your own API token.

It is an independent app. It is not affiliated with or endorsed by Cloudflare, Inc.

What it does

Dashboard DNS records
Analytics AI chat
  • Zones and DNS. Search, filter and edit records, toggle the proxy, import and export BIND files.
  • Security. Under Attack Mode, Development Mode and Pause Zone sit at the top of every zone. WAF custom rules, IP access rules, SSL/TLS settings.
  • Analytics. Requests, cache hit rate, bandwidth and threats over 1, 7 or 30 days.
  • Developer platform. Workers with live logs, plus KV, R2 and D1 browsers and Pages projects.
  • AI assistant. A security audit with a score, and a chat where you describe a change in plain language.
  • The rest. Multiple accounts, light and dark theme, biometric lock, 12 languages.

The stack

React Native 0.81, Expo SDK 54, Expo Router and strict TypeScript. Credentials live in Expo Secure Store, which is backed by the Android Keystore, and are sent only to api.cloudflare.com.

A few decisions turned out to matter more than the framework choice.

1. Never write an API payload from memory

Cloudflare's API is huge. Guessing a field name gives you a screen that looks fine and fails on save. So the repo carries a generated reference: a script reads the official OpenAPI schema and writes one markdown file per product into docs/cf-api/, covering 3,239 endpoints with their paths, query parameters, request fields and response shape.

npm run cf:schema   # download the OpenAPI schema
npm run cf:docs     # regenerate docs/cf-api/
Enter fullscreen mode Exit fullscreen mode

Every function in the API layer is written against that reference, with a typed interface per response:

export async function getHealthChecks(zoneId: string): Promise<CFResponse<HealthCheck[]>> {
  return get(`/zones/${zoneId}/healthchecks`);
}
Enter fullscreen mode Exit fullscreen mode

One function per endpoint, no mode flags, no any.

2. A scoped token should hide a section, not break the screen

Most people use API tokens with narrow permissions, which means a 403 is normal, not an error. Secondary requests go through Promise.allSettled, and a section whose request was refused simply does not render. The screen still works with whatever the token is allowed to see.

3. The AI proposes, you approve

Letting a model change DNS for you is a bad idea if it can act on its own. In the chat, the assistant replies with a proposed action as a card, for example "Add A record shop → 203.0.113.50", with Dismiss and Apply buttons. Nothing is sent to Cloudflare until you tap Apply.

AI security audit

The AI features use a small hosted backend. The app sends it the zone configuration needed to answer, and never the API token. That backend is the one part that is not in the public repo.

4. Twelve languages without typing twelve translations

Each feature adds its English strings to one small JSON file. A script translates them into the other 11 locales and merges the result, then checks that every locale has exactly the same keys:

node scripts/i18n-translate.js onboarding source.json
Enter fullscreen mode Exit fullscreen mode

Two lessons from doing this at scale:

  • Protect product names. A generic translator will happily turn "Under Attack Mode" or "Turnstile" into ordinary words. The script swaps brand names and {{placeholders}} for tokens before translating and restores them after.
  • Make the tokens digit-only. Word-shaped placeholders get "corrected" by some languages. Numbers survive.

Machine translation is still only a first draft. I rewrote the Indonesian strings by hand.

5. A demo mode for honest screenshots

Store screenshots should not show real domains or IP addresses. In development builds there is a demo switch that swaps the Axios adapter for one that serves fixtures: a fake account, a handful of zones on documentation IP ranges, analytics from a generator. Every screenshot in this post comes from that mode, on a real phone.

6. Store art as code

The Play Store screenshots are not drawn by hand. One HTML file lays out all eight frames as a single wide panorama, with a gradient that runs across them and a magnified callout that crosses from each frame into the next. Headless Chrome renders each frame, in each language, with one script. The app icon and the onboarding illustrations are built the same way, so changing a colour is a one-line edit followed by a re-render.

What is next

The roadmap in the repo tracks 54 batches of work. The priority is turning the remaining read-only screens into editable ones, then wiring more of the AI helpers into the screens where they are useful: explaining a traffic spike, writing a WAF rule from a sentence, explaining a Worker log line.

Try it

If your token is missing a permission, or a screen shows something odd, open an issue. Feedback on which Cloudflare product you most want on your phone is especially welcome.

Top comments (0)