[KongchangAI]
Tutorials· 2 min read· 1,409 words

Simon Willison's Full Process of Building an iNaturalist Observation Tool with Phone + Claude Code

Simon Willison's Full Process of Building an iNaturalist Observation Tool with Phone + Claude Code

Simon Willison built a full-stack iNaturalist tool on his phone with Claude Code while camping

During a camping trip, Simon Willison built a complete toolchain for displaying iNaturalist nature observation records using only his phone and Claude Code for Web. The project employs a three-layer architecture: a Python CLI for spatiotemporal clustering, Git Scraping for zero-cost automated data updates, and a static frontend page for displaying results. This case proves that when AI programming tools are mature enough and prompts are precise enough, developer productivity is no longer constrained by equipment—though architectural design remains a core human competitive advantage.

Overview

Simon Willison (renowned developer, creator of Datasette) built a complete toolchain for displaying iNaturalist nature observation records during a camping trip, using nothing but his phone and Claude Code for web. This case demonstrates how AI-assisted programming enables developers to rapidly complete full-stack development—from backend data processing to frontend display—under minimal conditions.

Simon Willison is one of the co-creators of the Django framework, and later created Datasette—an open-source tool that instantly transforms SQLite databases into interactive APIs and web interfaces. He is one of the earliest practitioners in the developer community to systematically explore LLM-assisted programming, regularly documenting his experiences with AI tools on his blog. His "Git Scraping" concept has been adopted by hundreds of open-source projects, becoming one of the standard patterns for lightweight data engineering.

Project Background: Why Code on a Phone

Simon has two separate accounts on iNaturalist (a global nature observation community platform), and he wanted to aggregate and display observation records from both accounts by time and location. The traditional approach would require hours of coding at a computer, but he chose a more challenging route—completing the entire project during a camping trip, using only his phone and Claude Code.

iNaturalist is a global citizen science platform jointly operated by the California Academy of Sciences and the National Geographic Society, with over 150 million observation records and millions of active users. Users upload photos of plant and animal observations, the platform uses computer vision models to assist with species identification, and community experts then verify the results. Verified "research grade" data is synchronized to the Global Biodiversity Information Facility (GBIF) for scientific research. The platform provides a comprehensive REST API that allows developers to query observation data by user, location, species, and other dimensions—this forms the data foundation for Simon's project.

This was not just a technical experiment, but proof that when AI programming tools are mature enough, developer productivity is no longer constrained by equipment.

Development Tool: Claude Code for Web

Claude Code is an AI programming tool from Anthropic designed for developers. Its web version allows users to collaborate with Claude at the code level directly through a browser. Unlike traditional IDE plugin-style AI assistants, Claude Code is more akin to a "pair programming partner" with full contextual understanding—capable of understanding project structure, generating multi-file code, executing command-line operations, and even interacting directly with GitHub for code commits. The web version's advantage is that it doesn't depend on a local development environment; only a browser is needed, making development on mobile devices possible.

Technical Architecture: Three-Layer Design Explained

Layer 1: Python CLI Data Processing Tool

First, he built a Python command-line tool called inaturalist-clumper for fetching and "clumping" observation records. The core logic groups observations that are within 2 hours of each other in time and 5 kilometers in geographic distance into the same clump. This aggregation strategy effectively simulates the natural boundaries of "one outing for observation."

The clumping logic here is essentially a spatiotemporal constraint-based clustering algorithm. The 2-hour time threshold and 5-kilometer distance threshold were not chosen arbitrarily—they simulate the typical spatiotemporal range of an outdoor nature observation activity. In terms of implementation, this is similar to a simplified version of DBSCAN (Density-Based Spatial Clustering): after sorting by time, adjacent observation records are sequentially checked to see if they satisfy the time and distance constraints, and if so, they're grouped together. Geographic distance calculations typically use the Haversine formula, computing the great-circle distance between two points on a sphere based on latitude and longitude. The advantage of this approach is O(n) computational complexity, suitable for processing thousands of observation records.

Layer 2: Git Scraping for Automated Data Updates

The second step was setting up the simonw/inaturalist-clumps repository, leveraging the "Git Scraping" technique that Simon himself popularized—using GitHub Actions to run data scraping scripts on a schedule, storing results as JSON files in the repository. The elegance of this approach lies in:

  • Data updates automatically on a regular schedule with no manual intervention
  • GitHub provides free static file hosting
  • JSON files can be fetched directly by frontend JavaScript via CORS
  • Git history provides natural data version management

Git Scraping is a data engineering pattern proposed and popularized by Simon Willison in 2020. The core idea is to use a GitHub repository as a "database": through GitHub Actions' cron scheduler (typically triggered hourly or daily), a script runs to fetch data from external APIs, writes results to JSON/CSV files in the repository, then auto-commits. Each data change produces a Git commit, meaning you not only have the latest data but also a complete change history. GitHub Pages or Raw URLs provide free CDN-level file hosting, and with CORS headers configured, frontend JavaScript can directly fetch these data files with absolutely no backend server required. This pattern is particularly suited for scenarios with moderate update frequency (minute-level or above) and moderate data volume (single files under 100MB).

Layer 3: Frontend Display Page

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

  • Fetch clumps.json data from a GitHub Raw URL
  • Display all observation records using iNaturalist's small thumbnails (small.jpg)
  • Use loading=lazy on images for lazy loading to optimize performance
  • Show a larger image (large.jpg) in an HTML modal when a thumbnail is clicked
  • Display species common names

The native HTML loading="lazy" attribute is a browser-level lazy loading implementation, first supported in Chrome in 2019 and now adopted by all major browsers. When an image element has this attribute set, the browser delays loading images outside the viewport until the user scrolls near them, only then initiating the network request. For Simon's project, an account might have hundreds or even thousands of observation records, each with a thumbnail. Loading all images at once would consume massive bandwidth and severely impact initial page load speed. Lazy loading ensures users only download images in the currently visible area, reducing initial page load time from potentially tens of seconds to 1-2 seconds.

Key Insights for AI-Assisted Development

This project has several characteristics worth noting for developers:

Minimal Development Environments Can Still Be Highly Productive

The entire project was completed on a phone—no IDE needed, no local runtime environment needed. Claude Code handled the bulk of code generation. This breaks the conventional wisdom that "full-stack development requires a heavy toolchain."

Prompt Engineering Determines Output Quality

Although Simon's prompt was just one paragraph, it contained complete technical specifications—data source URL, image URL patterns, interaction methods, performance optimization requirements (lazy loading), and feature details (species name display). This demonstrates how experienced developers collaborate efficiently with AI: the more precise the requirements, the more reliable the output.

Architectural Thinking Remains Humans' Core Competitive Advantage

AI helps generate code, but the overall architectural design (CLI → Git Scraping → Static Frontend) remains the wisdom of human developers. This serverless, low-maintenance architecture choice showcases the design philosophy of senior engineers. The operational cost of this architecture is nearly zero: GitHub Actions provides 2,000 free minutes of execution time per month, GitHub repositories provide free storage and CDN, the entire system requires no paid servers, and there are no traditional operational burdens like database maintenance, SSL certificate renewal, or server security patches. This is the ultimate embodiment of the "Serverless" philosophy—not using cloud functions to replace servers, but fundamentally eliminating the need for servers altogether.

Conclusion

Although this project is modest in scale, it perfectly illustrates the modern AI-assisted development workflow: developers handle architecture design and requirements definition, while AI handles code implementation. When tools like Claude Code are powerful enough and prompts are precise enough, you can complete a fully functional full-stack application even while camping on your phone. For developers looking to try AI programming, this is an extremely valuable reference case.

Key Takeaways

  • Simon Willison completed a full-stack tool development entirely on his phone with Claude Code while camping
  • The project uses a three-layer architecture: Python CLI data processing → Git Scraping auto-updates → Static frontend display
  • Git Scraping leverages GitHub Actions to periodically fetch data, achieving zero-server-cost data automation
  • Precise prompt design is the key to efficient AI-assisted development output—a single paragraph can define complete frontend application specifications
  • Architecture design remains the core value of human developers, with AI primarily handling the code implementation layer
#Claude Code#AI-assisted programming#Git Scraping#iNaturalist#Simon Willison#mobile development#serverless architecture
Share:

Related articles