How we built a single-file, offline satellite visualization app with AI. The method: Define a role for the AI, plan-then-proceed, and use evidence (show images, don’t just tell) to drive development.
We built a single-file, offline web app that visualizes two satellites and a ground station. It displays everything on a 2D map and a 3D globe, showing the field-of-view (FOV), line-of-sight (LOS), and offering CSV exports of contact windows. While AI authored the code, my friend and I managed the project’s scope, conducted reviews, and handled testing. This post details that entire process: the rules we established, how we verified the behavior, and why those decisions are crucial for anyone developing science tools with AI. Ultimately, the project was catalyzed by my friend’s initial questions.

Quick Overview
- Runs anywhere: Single-file HTML (vanilla JS/CSS), fully offline
- What you see: 2D world map and 3D globe with tracks, FOV footprints, and day/night shading
- Actors: Two satellites and one ground station
- Core logic: Inter-satellite LOS and ground-station access
- Dynamics: J2 secular precession
- Output: One-click CSV export of contact windows
The Story of Our App
This post lays out the major steps involved in developing our satellite-simulator app, showcasing the unique collaboration between a friend, myself, and AI. It primarily details the AI development workflow.
The AI (ChatGPT-5 Thinking, then Gemini 2.5 Pro) handled all the coding. My friend and I were responsible for the strategic side: setting the direction, reviewing the generated builds, and testing.
For a full feature tour, the complete user manual, and to download the application, please visit the project’s official GitHub repository: https://github.com/henkielp/Orbital-Contact-Analyzer
How It Started
The project began with a simple chat. I was demonstrating the capabilities of AI to a friend, and the topic quickly turned to AI programming.
My friend happened to have an existing Excel model: it took the positions of two satellites, drew their respective “can-see” circles (the geometric horizon), compared them, and calculated the distance between them.
That original spreadsheet became the seed for the general, offline, single-file web app we eventually built..
First prompt
“I want to do satellite orbiting the earth based on its Keplerian elements. I want to do field of view for that satellite. And then I want to do a second satellite. And then I want to display when those satellites have a line of sight with each other.”
The first output was a two-hour ground-track plot (below).

Development Loop (3–4 Weeks)
The work was structured in small, collaborative steps. While the AI (ChatGPT-5 Thinking, later Gemini 2.5 Pro) wrote the code, my friend and I drove the direction. I focused on setting the scope, handling reviews, and testing, while my friend contributed key feedback and ideas.
This partnership allowed us to continuously refine both the function and feel of the application.
Timeline:
- Week 1: Map prototype, basic LOS checks, initial FOV visuals
- Weeks 2–3: UI polish; 2D/3D workflow; visibility tweaks
- Week 4: J2-based precession (slow orbit drift)
What I Learned
Start With a Role
The results improved immediately once I started giving the AI a defined role, a step I initially missed. I now make it a habit to ask the AI to define its role at the beginning of any chat session.
For this project, the AI selected a role that clearly covered both the necessary physics and the final browser implementation:
Astrodynamics Web Engineer (Simulation & Visualization)
The role included specific responsibilities: keeping universal time (UTC/GMST) consistent, correctly converting ECI ↔ ECEF coordinates, handling standard orbital angles (ν→M), computing Line-of-Sight (LOS) and Field-of-View (FOV), and implementing all of it in a single-file HTML/JS app with a 2D map and 3D globe.
Why this matters: Starting with an “Astrodynamics Web Engineer” role would have prevented early reference-frame mistakes (like incorrect terminator motion and the wrong longitude sign). More broadly, a specific role tells any AI which “muscles” to flex; without it, models default to generic help and must infer goals, standards, and depth—slower and riskier.
Plan, Then Proceed
I implemented a “discuss first” step before making any changes. This mandate immediately improved the quality of the work and left us with reusable plans and checklists.
The key instruction I gave the AI was:
“Explain what you will do and how you will do it. Do not do anything until we have this discussion.”
By writing short plans before coding, the AI exposed assumptions before they could become bugs. This made our reviews faster—especially for complex features like J2 work and tricky line-of-sight (LOS) cases. “Plan first” doesn’t give the AI new outside knowledge—but it creates the missing specs (assumptions, constraints, success checks) the model didn’t have, so it can answer better.
One “Latest” File Prevents Old Bugs Returning
We often saw old issues resurface because the AI was patching older versions of code. To stop this, we enforced the use of a single, canonical “latest” HTML file for all subsequent changes.
We communicated the current build status using precise instructions like:
“Use the latest combined build that includes: immediate 3D texture draw, button colors, 2D FOV both green, reduced 2D track opacity, and marker halos.”
This practice was critical when verifying coordinate transformations. For example, converting from space coordinates (ECI) to the spinning-Earth view (ECEF) requires the precise rotation direction, such as Rz(−GMST). Using Rz(+GMST) causes subtle errors—like terminator drift or ground-track offsets—that look like simple UI bugs.
The Takeaway: Because we maintained that single canonical build, sign mistakes were quickly isolated and fixed, rather than being mistaken for minor visual shading or UI glitches.
Prevent Context Loss with a “One-Page Handoff”
I observed that as our chat sessions grew, the AI began losing context. Context, in this case, includes the latest app build, open issues, and the supporting evidence (like console errors or screenshots) needed for debugging. Once a thread becomes too long, this vital information is forgotten.
To solve this, before starting a new chat instance, I now create a one-page handoff document. This handoff summarizes the current scope, immediate goals, open bugs/to-dos, and recent fixes, ensuring the AI is always operating from the most up-to-date position.
Replicate Style: Have the AI Write the Prompt
A highly effective strategy for maintaining consistency was letting the AI draft the very prompt needed to replicate its own work in a new chat.
The request:
“Draft a prompt I can paste into another chat to maintain the structure, tone, and guidelines for the Project Log and Release Notes we developed here.”
This self-written prompt captured everything—the specific role, tone, structure, and technical definitions (e.g., what FOV/LOS mean)—so a new chat could instantly produce consistent documentation without us having to start from scratch.
By using both the one-page handoff (for facts) and the reusable prompt (for style), we successfully rebooted this long project without sacrificing accuracy or consistency.
Show, Don’t Just Tell (Use Images)
Screenshots were essential for communicating visual issues, such as problems with terminator shading, overly busy tracks, or inconsistent button colors.
By seeing the image, the AI was able to suggest small, targeted updates—like reducing 2D track opacity and standardizing Field-of-View (FOV) colors. These changes immediately made satellite footprints and horizons much easier to read.
Paste Console Errors Verbatim
The fastest way to fix a non-visual bug is to copy the exact browser error and paste it into the chat, asking the AI for the solution.
This approach often resulted in a one-exchange fix that got the current build working again with minimal back-and-forth.
Reusable Tactics: Key Takeaways
- Start with a Defined Role: Define the AI as an Astrodynamics Web Engineer to preempt frame and units mistakes.
- Plan, Then Proceed: Require a short plan before any code change; this surfaces assumptions
- Keep One Canonical Build: Maintain a single, “latest” HTML file to stop old bugs from reappearing.
- Handoff When Chats Grow Long: Use a one-page recap (scope, open bugs, latest file) to reset the AI’s context.
- Replicate Style: Let the AI author the reusable prompt you’ll paste into a new chat instance.
- Use Evidence Inputs: Paste screenshots and verbatim console errors to drive immediate fixes.
What the App Can Do
Visualization & Interactivity
- 2D Map & 3D Globe: Easily toggle the view using the Projection selector. Use Focus Mode for full-screen demonstrations.
- Inertial View (3D): Keep the satellites’ orbital planes fixed in space while the Earth rotates underneath.
Data & Export
- Tables & CSV Export: Built-in tables list the intervals for both Inter-Satellite Line-of-Sight (LOS) and Ground-Station Access. A single click saves all data to a CSV file.
Limitations (Please Read)
This tool is designed for first-order analysis and educational purposes only. It runs entirely within your browser.
What the App Models:
- J2 Perturbation: Included for modeling secular precession (long-term drift of the node and argument of perigee).
- Spherical Earth: Used for all ground-visibility geometry.
What the App Does NOT Model:
- Atmospheric drag or solar radiation pressure (SRP).
- Third-body perturbations (e.g., Moon/Sun gravity).
- Terrain features.
- The WGS-84 ellipsoid (it uses a spherical Earth model).
- Short-period or higher-order J2 effects.
Expected Errors: Expect small errors in some ground projections. Specifically, the spherical-Earth horizon model can slightly misplace the edges of long Field-of-View (FOV) footprints at high latitudes compared to a model using the WGS-84 ellipsoid.
Crucially, for mission-critical work, you must use a high-fidelity, validated software suite.
Download the App & Get Involved
I’m excited to announce that the Orbital Contact Analyzer is now publicly available on GitHub. The repository is the central hub for this project and contains everything you need to get started:
- The final application (the single .html file)
- The complete User Manual with detailed feature explanations
- Example scenarios to demonstrate key concepts like Sun-synchronous orbits
I encourage you to visit the repository to download the app and explore the documentation. Getting started is simple and requires no installation. If you have any feedback or find any issues, please feel free to open an issue on GitHub.
https://github.com/henkielp/Orbital-Contact-Analyzer
Credits & Acknowledgments
Imagery
The 2D map and 3D globe textures used in the app are based on NASA Visible Earth’s image set: “Blue Marble: Land Surface, Shallow Water, and Shaded Topography.”
Collaboration
Thank you to my friend Jay for their invaluable ideas, feedback, and review throughout the entire project.
AI Assistance
This post was drafted and edited with help from ChatGPT-5 Thinking. Earlier code iterations also drew on Gemini 2.5 Pro. All final choices, errors, and opinions, however, are strictly my own.
