The goal of this project is to create a general-purpose infrastructure for using the Gemini internet protocol over the I2P network.
The application will be a client capable of fetching and rendering Gemtext (text/gemini) over I2P. It will be built entirely in pure Go, targeting both Linux and Android platforms using the Fyne toolkit. To ensure a seamless and self-contained experience, the application will communicate directly with the local I2P router using the SAM (Simple Anonymous Messaging) API, avoiding the need for the user to manually configure external I2P tunnels or proxies.
In the future, this infrastructure will be expanded to serve and render RSS feeds by converting them to Gemtext.
- Language: Pure Go.
- UI Framework: Fyne (Cross-platform support for Linux and Android).
- Network Layer: I2P SAM API (likely
github.com/eyedeekay/sam3or similar pure Go SAMv3 library). - Zero-Configuration: The app must dial
b32.i2paddresses directly via the SAM bridge (default127.0.0.1:7656) without requiring external hidden service tunnel configuration. - Protocol & Transport: The client will support transport protocols (like
gemini://and eventuallyipfs://) to fetch data, but content rendering and processing will be strictly driven by MIME types (e.g.,text/gemini,application/rss+xml,text/plain). - Feed Architecture: Avoid pseudo-protocols like
rss://orfeed://. Instead, the client will inspect the MIME type returned by the server (e.g., via the Gemini header). If an RSS/Atom MIME type is detected, the payload will be routed through an internal "Feed Converter" that transforms the XML into standard Gemtext before passing it to the AST parser for UI rendering. - Dependency Management: When selecting third-party libraries, strongly prefer libraries listed in pkg.go.dev that are recently maintained, have a healthy ecosystem, and are demonstrably popular (e.g., strong module adoption).
Two parallel client implementations are under evaluation:
mipzda-fyne/— Original implementation using the Fyne UI toolkit. Cross-platform (Linux, Android). Text in rendered Gemtext is not selectable (a known Fyne limitation up to v2.7.3).mipzda-gio/— Port using the Gio UI toolkit. Same target platforms. Body text is selectable viawidget.Editor(read-only). Gio uses an immediate-mode programming model. Does not include the embedded I2P router (requires an externali2pd/SAM bridge).- TODO: Layout polish needed — heading sizes, link styling, padding, and overall visual hierarchy need refinement to match a browser-quality reading experience.
See lessons-learned.md for technical findings, known bugs, and implementation decisions made during development.
- Initialize Go project and Fyne dependencies (
hello-fyne). - Configure build and deployment pipelines for Linux desktop and Android emulator.
- Design the basic browser UI (Address bar, Go button, Content area, Scroll container).
- Implement a basic Gemtext (
text/gemini) parser in Go (usinggithub.com/mcecode/gemtext-parser). - Create a Fyne renderer/widget to beautifully display parsed Gemtext (Headers, links, lists, blockquotes, preformatted text).
- TODO: Text selection spanning multiple formatted widgets (RichText, Labels) is not currently supported natively by Fyne (even up to v2.7.3). We need to implement a workaround (e.g., a "Copy Document" button, or an alternative selectable text view) before final release.
- Research and integrate a pure Go I2P SAM v3 client library.
- Create a connection manager that connects to the local I2P SAM bridge.
- Implement a custom Go
net.Dialeror equivalent interface that routes traffic through the SAM bridge to destinationb32.i2paddresses.- TODO: The embedded
go-sam-bridgeimplementation inside the client is currently unstable (exhibiting duplicate session EOF drops or failing to route). We need to debug the embedded router initialization so the client can run entirely standalone without an externali2pddependency before final release.
- TODO: The embedded
- Implement the Gemini protocol client (URL parsing,
gemini://scheme handling, request formatting). - Implement TLS over the I2P SAM connection (Gemini requires TLS; consider TOFU - Trust On First Use - implementation for self-signed certificates over I2P).
- Connect the Gemini client to the UI, allowing a user to type a
b32.i2pGemini URL and view the fetched Gemtext.
- Verify functionality, UI responsiveness, and Gemtext rendering on Linux.
- Verify functionality, UI responsiveness, and Gemtext rendering on Android (Emulator & Physical Device).
- Implement navigation history (Back/Forward).
- Implement an RSS/Atom feed fetcher over the established I2P infrastructure.
- Build a conversion layer that dynamically transforms RSS XML into standard Gemtext format.
- Integrate the converted RSS feeds into the client UI for seamless reading.