Phone + Claude Code: Building an iNaturalist Observation Display Tool While Camping

Simon Willison built a full iNaturalist display system with just a phone and Claude Code while camping.
During a camping trip, Simon Willison built a complete iNaturalist observation display tool using nothing but his phone and Claude Code. The project features a three-layer architecture: a Python CLI data clustering tool, Git Scraping for automated updates, and a pure frontend display page—all deployed at zero cost with zero servers using the GitHub ecosystem. This case demonstrates how AI coding assistants enable developers to turn inspiration into reality anytime, anywhere.
Background: A Spontaneous Build During a Camping Weekend
Simon Willison—renowned developer and creator of Datasette—built a complete iNaturalist observation display tool from scratch during a camping trip, armed with nothing but his phone and Claude Code. This case perfectly demonstrates how AI coding assistants are making "code anywhere, anytime" a reality.
Simon Willison is one of the co-creators of the Django web framework and later built Datasette—a tool that instantly transforms SQLite databases into interactive APIs and data exploration interfaces. His technical philosophy has always emphasized "small, sharp tools": each tool does one thing well, but they can be combined to solve complex problems. This modern take on the Unix philosophy runs through all his recent projects, from sqlite-utils to the llm command-line tool, and now this camping project.
iNaturalist is a global nature observation community platform, co-founded by the California Academy of Sciences and the National Geographic Society. It currently has over 2 million active users and more than 150 million observation records. When users upload photos of plants and animals, the platform combines computer vision models (species identification systems trained on convolutional neural networks) with expert community review to confirm species. iNaturalist provides a comprehensive RESTful API that allows developers to query observation data by user, location, time, taxonomic classification, and other dimensions, returning structured JSON data including geographic coordinates, taxonomic information, and multi-resolution image URLs. Simon has two iNaturalist accounts and wanted to aggregate and display observations from both accounts on a single page, organized by time and location.
Three-Layer Architecture: An Elegant Composition of Small Tools
The entire project consists of three independent yet tightly coordinated components, embodying Simon's longstanding "composable small tools" philosophy. This architectural approach draws from Unix's pipe design principles—each component communicates through standardized data formats (JSON in this case), deploys and iterates independently, and any layer can be replaced without affecting the others.
Python CLI Data Processing Tool
Simon first built inaturalist-clumper, a Python command-line tool that fetches observation data from the iNaturalist API and performs "clumping" processing. The default clumping rules are: observations that are within 2 hours of each other and within 5 kilometers geographically are grouped together.
This design is quite clever—it essentially reconstructs a user's "single outing" behavior. When you walk through a park for two hours, all the plants and animals you photograph naturally belong to the same "observation trip." From an algorithmic perspective, this is a greedy clustering method based on spatiotemporal constraints: after sorting by time, it sequentially checks whether adjacent records satisfy both time and spatial thresholds—if yes, they're added to the current cluster; if not, a new cluster begins. Compared to general-purpose clustering algorithms like DBSCAN, this approach has lower computational complexity (linear time) and more intuitive semantics—it assumes human observation behavior is temporally continuous, meaning a single walk won't have a three-hour gap. The 5-kilometer spatial threshold covers most walking or short-drive observation scenarios.
Git Scraping for Automated Data Updates
Simon leveraged his own Git Scraping technique, creating the inaturalist-clumps repository. GitHub Actions runs the clumper tool on a schedule, writes results to a clumps.json file, and commits it to the repository.
Git Scraping is a lightweight data tracking pattern that Simon proposed and popularized in 2020. The core idea is: use GitHub Actions' cron scheduled tasks to periodically fetch external data sources, write results to repository files, then run git add and git commit. If the data hasn't changed, Git produces no new commit; if the data has changed, the changes are precisely recorded in Git's diff history. This not only achieves automated updates but naturally provides version history for the data—you can trace back to the data state at any point in time and analyze trends. Compared to traditional crawler + database approaches, Git Scraping requires no database server maintenance, no data migration scripts, and all infrastructure is provided free by GitHub. Currently, hundreds of public projects use this pattern to track everything from government open data to flight information.
More critically, JSON files on GitHub can be accessed directly by frontend JavaScript via CORS cross-origin requests through raw.githubusercontent.com—a free API and CDN in one step.
CORS (Cross-Origin Resource Sharing) is a browser security mechanism: by default, JavaScript in a webpage can only request resources from the same origin (same protocol + domain + port) as the current page. When the frontend is hosted on github.io and data files are on raw.githubusercontent.com, this constitutes a cross-origin request. GitHub's Raw file service sets Access-Control-Allow-Origin: * in its HTTP response headers, explicitly allowing frontend code from any domain to access these files. This means you only need to push a JSON file to a GitHub repository and it automatically becomes a globally accessible read-only API endpoint—no server configuration, API gateway, or CDN setup required. For personal projects with modest data volumes and low update frequencies, this is an extremely elegant zero-cost solution.
Pure Frontend Single-Page Display Application
The final step was building the frontend display page. Simon sent Claude Code a precise prompt requesting an HTML application that:
- Fetches JSON data from GitHub via
fetch() - Displays all observations using iNaturalist thumbnail URLs (small.jpg)
- Implements lazy loading with
loading=lazyfor images - Shows a large image (large.jpg) in a modal when a thumbnail is clicked
- Displays common species names
A prompt of less than 100 words fully described a complete single-page application. The loading=lazy mentioned here is a native HTML lazy loading attribute (supported by major browsers since 2019) that tells the browser to only begin downloading images when they're about to enter the viewport. For pages with many images, this significantly reduces initial load time and bandwidth consumption. In scenarios like iNaturalist, a single data fetch might include hundreds of observation photos, making lazy loading an essential performance optimization.
Notable Engineering Practices
Complete Development Workflow on a Phone
The entire project was completed entirely on a phone during camping, thanks to the web version of Claude Code. Claude Code is an AI coding assistant from Anthropic that supports generating, modifying, and debugging code through conversation. Unlike traditional IDEs (such as VS Code or JetBrains products), it doesn't require local installation of compilers, package managers, or runtime environments—all code generation and logical reasoning happens in the cloud, and users only need a browser and internet connection. This means developers can complete the entire process from requirement description to code generation in a mobile browser, then push code to a repository via GitHub's web interface or API, with GitHub Actions handling subsequent builds and deployments.
This isn't a simple demo—it's a complete system with backend data processing, an automation pipeline, and frontend display. AI coding assistants are redefining the boundaries of what constitutes a "development environment"—your development environment is anywhere you can type.
Zero-Cost Serverless Architecture
This project has no servers in the traditional sense:
| Layer | Implementation | Cost |
|---|---|---|
| Data Processing | GitHub Actions free compute | Free |
| Data Storage | GitHub Repository | Free |
| Data Distribution | GitHub Raw CDN (CORS-enabled) | Free |
| Frontend Hosting | GitHub Pages | Free |
Zero operational costs, zero server management, yet fully functional with automatic updates. For personal projects and small tools, this is nearly the optimal solution. It's worth noting that GitHub Actions provides 2,000 free minutes per month for public repositories, GitHub Pages has a 1GB storage limit per site and 100GB monthly bandwidth limit, and Raw CDN also has rate limits. But for personal tool-level projects, these limits are almost never reached. The real limitation of this architecture is that it's only suitable for read-heavy, write-light scenarios with manageable data volumes—once you need user-interactive writes, real-time data processing, or large-scale concurrent access, you'll need to introduce actual backend services.
Prompt as Specification Document
Simon's prompt to Claude Code is exemplary: it precisely specifies the data source URL, image URL patterns, interaction behavior (click to enlarge), performance optimization (lazy loading), and content requirements (species names). No vague descriptions—every sentence is a verifiable functional requirement.
This reminds us: the core skill in AI-assisted programming is the ability to describe requirements precisely. Vague instructions produce vague results, while structured requirement descriptions enable AI to generate usable code in a single pass. This skill is essentially the same as writing a traditional Software Requirements Specification (SRS). The difference is that traditional SRS documents are written for human development teams and must account for communication efficiency and potential ambiguity; prompts written for AI are closer to formal specifications—the more specific, verifiable, and unambiguous they are, the higher the quality of AI output. Simon's prompt works because, as a veteran developer, he can complete the architecture design in his head and then precisely communicate implementation details to the AI. This shows that AI programming tools amplify a developer's existing design capabilities rather than replacing them.
Conclusion: The True Value of AI Programming Tools
This small project distills multiple trends in modern development: AI-assisted programming lowers development barriers and environment dependencies, Git Scraping provides a lightweight data automation solution, and the GitHub ecosystem serves as free full-stack infrastructure. When an experienced developer meets the right AI tools, even in a camping tent with just a phone, they can deliver a complete, functional product in a short time.
This is perhaps the most valuable use case for AI programming tools—not replacing developers, but enabling them to rapidly turn inspiration into reality at any time, in any place. From a broader perspective, this case represents an emerging new development paradigm: a developer's core value shifts from "writing code" to "designing systems and describing requirements," AI handles the translation from requirements to implementation, and cloud infrastructure (GitHub, Cloudflare Workers, Vercel, etc.) eliminates operational burden. In this paradigm, one person plus one AI can accomplish what previously required a small team several days to deliver—provided that person possesses clear architectural thinking and precise requirement articulation skills.
Key Takeaways
- Simon Willison built a complete iNaturalist observation display system using only his phone and Claude Code while camping
- The project uses a three-layer architecture: Python CLI data clustering tool + Git Scraping automated updates + pure frontend display page
- Leverages the GitHub ecosystem (Actions + Raw CDN + Pages) to achieve zero-cost, zero-server full-stack deployment
- A precise prompt of less than 100 words enabled AI to generate a fully functional single-page application
- Demonstrates how AI coding assistants make "develop anywhere, anytime" a reality
Related articles
TutorialsChatGPT Plus Subscription Guide: Are GPT-5.5, image-2, and Codex Worth the Upgrade?
A detailed look at ChatGPT Plus features — GPT-5.5, image-2, and Codex — with a Plus vs Pro comparison and a complete step-by-step subscription guide for users outside the US.
TutorialsHarness AI Engineering in Practice: Using Claude Code to Master Enterprise-Level E-Commerce Development
Deep dive into Harness AI Engineering: master enterprise e-commerce development with Claude Code using the Rules, Skills, Wiki, and Changes framework.
TutorialsCursor + Codex Dual-IDE Collaboration: A Practical Methodology for Open-Source Project Customization
A complete methodology for open-source project customization based on real-world experience, detailing the Cursor+Codex dual-IDE workflow, seven-stage process, MVP validation, and AI source code reading techniques.