Code structure
December 28, 2025 ยท View on GitHub
This is probably not the most obvious code base to get into, and some unidiomatic choices were made.
Hopefully this can help potential contributors to get a better understanding of the code, and the unidiomatic choices - perhaps event come with better, more idiomatic solutions to the problems.
browser/ # Main entry point,
internal/
clock/ # Controls the passing of simulated time
code-gen/ # Code generator. Not documented here!
constants/ # String constants, e.g., BUG issue URLs for error messages
dom/ # Parts of the DOM API not yet available to client code.
entity/ # Functionality for "entities"
html/ # XMLHTTPRequest implementation
gosthttp/ # Helper for handling HTTP requests
interfaces/ # Interfaces generated from webref specs
url-interfaces/ # Interfaces for the URL spec.
log/ # Logging helpers
test/ # Test code.
integration/ # Contains a simple go web app for testing
testing/ # Test helpers
dom/ # Core dom functionality. Nodes, elements, attributes, document, etc.
event/ # EventTarget and Event types
html/ # Window, HTMLDocument, and specific HTML element implementations
logger/ # Provides a way for client code of receiving log messages
scripting/ # Impementing of scripting engines
internal/
scripttests/ # Common test suite for JavaScript implementations
js/ # Defines the interface for a script engine
codec/ # Conversion between Go and JS values
dom/ # Implementation of the DOM API
html/ # Implementation of the HTML DOM API
v8engine/ # Scripting support using v8 (and CGo)
sobekengine/ # scripting support using sobek, a pure Go engine
testing/ # Provides usable test helpers for users of the library
gomega-matchers/ # Matchers useful for users of the Gomega library
url/ # Implementation of URL behaviour
Entities
Package internal/entity defines the ability to store arbitrary data in an
entity.
This allows Gost-DOM to make sure the same JavaScript object is always returned for the same Go representation of a DOM element. But in a way that the JavaScript engine is completely decoupled from the Go implementation.
The first time a Go DOM element is exposed to JavaScript, the script bindings create the JavaScript object and stores it as a component on the Go entity. The second time, the same DOM element is requested from JavaScript, the script bindings can find the previously created object and return it.
Structure loosely follows Web APIs
The web standards defines a series of named APIs. The code attempts to follow this to the extend possible.
browser/urlcorresponds to the URL APIbrowser/domcorresponds to the DOM APIbrowser/htmlcorresponds to the HTML DOM API
Following this structure strictly isn't without challenges. An HTMLFormElement
dispatches formdata events, referencing FormData objects. FormData is
defined in the XMLHttpRequest API, yet
the FormData constructor accepts an HTMLFormElement as an optional
constructor argument, causing a circular reference. This FormData currently
exists in the html package.
Heavy use of internal packages
In order to keep as much freedom for refactoring without breaking compatibility, new code is largely placed in internal packages until it's known if it provides value to test code; and the public API seems stable.
For example, the XMLHttpRequest can be constructed from and used from JavaScript, but it doesn't seem to have any value to provide to Go code. Go code can already make HTTP requests, so using the clunky XHR interface doesn't seem to provide any value.
Internal interfaces are for verification
Package browser/internal/interfaces contain interfaces generated from web IDL
specifications. The interfaces are not referenced in production code, but test
code for the URL type uses this interface. This effectively makes it a static
check, that the URL type conforms to the web IDL specifications.