[KongchangAI]
Product Reviews· 2 min read· 1,382 words

Building an iNaturalist Observation Tool Entirely on a Phone with Claude Code

Building an iNaturalist Observation Tool Entirely on a Phone with Claude Code

Simon Willison built a zero-cost serverless web app on his phone with Claude Code while camping

During a camping trip, Simon Willison built a web tool for displaying iNaturalist nature observations entirely on his phone using Claude Code. The project features a three-layer architecture: a Python CLI tool performs spatiotemporal clustering to intelligently group observation data, GitHub Actions periodically scrapes data via a Git Scraping pipeline, and a static frontend page was generated from a single precise prompt. The entire system requires no server, has near-zero maintenance cost, and demonstrates both the feasibility of AI-assisted mobile programming and the importance of precise prompt engineering.

Project Background: A Mobile Coding Experiment While Camping

Simon Willison (renowned developer and Datasette creator) completed the development of a full web tool entirely using his phone and Claude Code during a camping trip. The tool displays his observation records on iNaturalist (a nature observation community platform), intelligently grouping them by time and location.

Simon Willison is one of the co-creators of the Django framework and later built Datasette — an open-source tool that instantly transforms SQLite databases into interactive APIs and web interfaces. He has long advocated for data democratization and low-barrier data exploration, and Git Scraping is a practical pattern he proposed under this philosophy. His tools repository contains numerous single-page web tools generated with AI assistance, and has become a benchmark collection for AI programming practices.

iNaturalist itself is a citizen science platform jointly operated by the California Academy of Sciences and the National Geographic Society, with over 200 million biological observation records worldwide. After users upload photos of wildlife, community members and AI models assist with species identification. The platform provides a comprehensive RESTful API supporting queries by user, location, time, and other dimensions — providing a stable data source for Simon's project.

This project demonstrates the practical capability of AI-assisted programming on mobile devices, while also showcasing an elegant "Git Scraping" data pipeline architecture.

Technical Architecture: A Three-Layer Zero-Cost Solution

Python CLI Tool: Data Collection and Spatiotemporal Clustering

Simon first built a Python command-line tool called inaturalist-clumper to fetch observation data from the iNaturalist API and perform "clumping" processing. The default clustering rule groups observations that are within 2 hours of each other and within 5 kilometers geographically.

Spatiotemporal Clustering is a classic problem in geographic information science. Common algorithms include ST-DBSCAN (density-based spatiotemporal clustering) and simple threshold segmentation. Simon uses the latter — performing greedy grouping with a time threshold (2 hours) and spatial threshold (5 kilometers): after sorting by time, adjacent observations are sequentially checked to see if they simultaneously satisfy both threshold conditions, and if so, they're assigned to the same group. This approach has low computational complexity, making it ideal for personal projects with modest data volumes.

This design is highly practical — when you're doing nature observation at a location, multiple photos taken within a short time naturally belong to the same "outing," and spatiotemporal clustering automatically reconstructs this logical relationship.

Git Scraping Data Pipeline: GitHub Actions Automation

Next, he created the simonw/inaturalist-clumps repository, using GitHub Actions to periodically run the CLI tool and write results to a clumps.json file.

Git Scraping is a data collection pattern Simon has long promoted: leveraging GitHub Actions' scheduled task capability to periodically scrape data and commit it to a Git repository. The core idea is using a Git repository as a time-series database. GitHub Actions provides 2,000 free execution minutes per month for public repositories. Each execution pulls from an external data source, generates structured files, and performs a git commit. Since Git naturally records the diff of each commit, developers can trace historical data changes through git log and git diff. Simon first proposed this concept in 2020, and hundreds of open-source projects now use this pattern to track government data, API changes, price fluctuations, and more.

The benefits include:

  • Automatic data updates with no server maintenance required
  • Git history provides natural version tracking
  • GitHub-hosted files support CORS cross-origin access, allowing direct calls from frontend JavaScript

The last point deserves elaboration: GitHub's raw.githubusercontent.com domain sets the Access-Control-Allow-Origin: * response header by default, meaning any webpage's JavaScript code can directly request files under this domain via fetch() without configuring a proxy server. This characteristic allows JSON files in GitHub repositories to serve as free static API endpoints — a key technical foundation enabling the Git Scraping pattern to seamlessly integrate with pure frontend applications.

Frontend Display Page: Done with a Single Prompt

The final step was building the frontend display page. Simon issued a precise prompt to Claude Code, requesting an HTML application that:

  • Fetches JSON data from GitHub via fetch()
  • Uses iNaturalist's small thumbnails (small.jpg) to display all observations
  • Adds loading=lazy for image lazy loading
  • Shows a large image (large.jpg) in an HTML modal when a thumbnail is clicked
  • Displays species common names

loading="lazy" is an HTML-native deferred loading attribute implemented by the browser. When an image element has this attribute set, the browser only initiates the network request when the image is about to enter the viewport, rather than requesting all images at once during page load. For pages with many thumbnails, this technique significantly reduces initial page load time and bandwidth consumption. Previously, developers needed to rely on the Intersection Observer API to manually implement similar functionality, but the introduction of the native attribute dramatically lowered implementation costs.

The entire frontend page was developed with a single prompt and ultimately deployed in his tools repository.

Noteworthy Design Principles

Serverless Architecture: Near-Zero Maintenance Cost

The entire system has no traditional backend server:

  • Data collection is handled by GitHub Actions
  • Data storage uses a Git repository
  • Data distribution leverages GitHub's CDN
  • The frontend is pure static HTML/JS

This architecture has near-zero maintenance costs and is completely free. For personal projects and small-scale data display needs, this is an extremely cost-effective solution.

Validating the Feasibility of Mobile AI Programming

Simon specifically mentioned completing this project "entirely on my phone." This demonstrates that Claude Code already has sufficient capability to let developers complete meaningful projects without a traditional development environment.

Claude Code is a command-line AI programming tool from Anthropic that supports code generation, file editing, and project management through natural language instructions in a terminal environment. On mobile devices, developers can run command-line tools through terminal emulators like Termux (Android) or iSH/a-Shell (iOS), or connect remotely to cloud development environments via SSH. Simon's practice shows that for prompt-driven AI programming workflows, the input limitations of a phone don't pose a substantial obstacle — the key bottleneck shifts from code writing to the precision of requirement descriptions.

For scenarios like weekend camping, the combination of a phone and an AI programming assistant demonstrates tremendous flexibility. This also means developers are no longer tied to their computers — fragmented time can equally produce valuable code.

Prompt Engineering: Precise Description as a Key Skill

Interestingly, Simon's prompt was highly specific — including exact URL patterns, interaction behavior descriptions, and functional requirements. This ability to write precise prompts is itself a key skill for efficiently using AI programming tools. Vague requirement descriptions often lead to repeated revisions, while providing complete constraints in one go significantly improves development efficiency.

This actually reflects an important paradigm shift in the AI programming era: a developer's core competency is shifting from "how to write code" to "how to precisely describe requirements." In traditional software engineering, Software Requirements Specifications (SRS) are typically written by product managers while developers handle implementation. In AI-assisted programming scenarios, the process of writing precise prompts is essentially requirement specification — only the executor has changed from a human programmer to an AI model.

Summary: Best Practices for Personal Data Tools

Although this project is modest in scale, it perfectly demonstrates the workflow of modern AI-assisted development: decomposing the problem into three clear layers — data collection, data pipeline, and frontend display — implementing each layer with the simplest tools possible, and combining them into a practical application.

For developers looking to quickly build personal data display tools, the combination of Git Scraping + GitHub Actions + static frontend is an architectural pattern worth referencing, while Claude Code makes the entire development process lighter and more efficient.

Key Takeaways

  • Simon Willison built a complete web application entirely on his phone using Claude Code during a camping trip
  • The project uses the Git Scraping pattern with GitHub Actions for periodic data fetching, achieving a zero-cost serverless architecture
  • A Python CLI tool intelligently groups iNaturalist observations through spatiotemporal clustering (2 hours / 5 kilometers)
  • The frontend display page was AI-generated from a single precise prompt, supporting lazy loading and modal large image preview
  • The overall architecture demonstrates elegant data pipeline design: GitHub Actions collection → Git storage → CDN distribution → static frontend consumption
#Claude Code#Git Scraping#GitHub Actions#serverless architecture#AI-assisted programming#iNaturalist#Simon Willison
Share:

Related articles