Library / SDK
google/wwwbasic avatar
google/wwwbasic

wwwBASIC: running BASIC in the browser with a JavaScript compiler underneath

wwwBASIC is an implementation of BASIC that runs on Node.js and the Web.

1,151 stars62 forksJavaScriptApache-2.0

At a glance

What is it?
wwwBASIC parses BASIC source and compiles it to JavaScript at load time, then binds it to a canvas or a console so old programs run on the web. It is a small, single-file project with an explicitly unstable extension mechanism.
Who is it for?
wwwBASIC suits a team that wants to publish a small BASIC program on a web page, port a historical listing, or teach BASIC without installing anything, and it does not suit a team that needs a supported, stable extension API or a production language with a maintained test suite.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A BASIC that compiles to JavaScript instead of interpreting a line at a time

wwwBASIC is a BASIC implementation aimed at the browser. The design decision that matters is stated plainly in the feature list: the source is parsed and compiled to JavaScript at load time. That is not a detail of implementation trivia. It means a program is turned into JavaScript once, when the page loads, rather than being interpreted statement by statement while it runs, so the resulting program runs on the same engine as the surrounding page.

The scope is deliberately narrow. The README lists graphics with 24-bit color plus PSET, LINE and CIRCLE, and input through INKEY$ and GETMOUSE. That is the whole stated surface, and it is short enough to read in a minute. There is no mention of file I/O, networking, floating point formats or a built-in database, and no claim of dialect compatibility with any particular classic BASIC other than the programs the project itself chose as milestones.

For a reader deciding whether to use it, that narrowness cuts both ways. A program that draws circles and reads the keyboard will work. A program expecting the full Commodore or BBC BASIC standard library will not, and the README does not promise one.

The first program on a page needs two script tags

The embed path is the shortest demonstration of the project. A page loads the interpreter from the project's GitHub Pages site, then declares a script block with the type text/basic that the interpreter picks up:

html
<!DOCTYPE html>
<html>
  <head>
    <script src="https://google.github.io/wwwbasic/wwwbasic.js"></script>
    <script type="text/basic">
      PRINT "Hello World!"
      FOR i = 1 to 10
        PRINT "Counting "; i
      NEXT i
    </script>
  </head>
</html>

By default wwwBASIC processes script tags of type text/basic, which is why nothing else in the markup calls the interpreter. The FOR and NEXT loop is standard BASIC, and PRINT with a semicolon is how the counter appears on the same line as the text.

The hosted script URL is convenient for a page you control, and it is also a dependency you do not control. A deployment that must not reach out to GitHub Pages at runtime has to vendor wwwbasic.js from the repository instead, since the same file is committed at the top level of the repository as wwwbasic.js and wwwbasic.mjs.

Running the same program from Node.js

The interpreter is also usable as a Node.js module, which is what you want for a script that draws on an off-screen surface or for tests. Two installation paths are offered, from npm or from a clone of the repository:

bash
npm install -S wwwbasic
bash
git clone https://github.com/google/wwwbasic.git

After that, the module is loaded and the program text is handed to basic.Basic:

js
var basic = require('wwwbasic'); // from NPM
// var basic = require('./wwwbasic.js'); // from within the cloned repository directory

// An ESM import is also available from wwwbasic.mjs
// import basic from "wwwbasic.mjs";

basic.Basic(
`
PRINT "Hello World!"
FOR i = 1 to 10
  PRINT "Counting "; i
NEXT i
`);

The package manifest points its main entry at wwwbasic.js and lists the test script as ./test/run-tests.sh. The CommonJS form and the ESM form are both supported, and the repository ships a wwwbasic.mjs entry alongside the main file for the ESM import path. Note the version in package.json is 1.0.2, so a published release trail through npm is short, and the repository itself has no GitHub releases at all.

Bindings are the extension point, and the README calls them semi-unstable

The interpreter does not own the screen. It calls out to bindings supplied by the host, and the README states this plainly: external bindings are currently considered a semi-unstable feature, use with caution. That sentence should govern any plan to build on top of this project.

The options object passed to basic.Basic carries the switch to turn debugging on and a dictionary of external bindings:

js
basic.Basic(codeText, {
  debug: true  // or false,
  bindings: {
    // a dictionary of external bindings, see below.
    name: myfunc,
  },
});

Two sets of bindings ship by default. basic.ConsoleBindings() provides the default set, and basic.GraphicsBindings(canvas) provides the canvas set, which is what connects PSET, LINE and CIRCLE to a real drawing surface. The foundational binding contract is small: PutCh(ch) prints one character, PutCh(undefined) flushes the buffer, and Halt() prints any final message at END. Input bindings are marked as a TODO in the source documentation, which tells you where the project thinks it is incomplete.

Adding a statement follows a naming convention you can read off a page

Custom statements and procedures are added with a naming convention rather than a registration API, and the convention is spelled out. A binding is named kind_name_arguments, where kind is statement or call, name is the lowercased subroutine or statement name, and arguments is a one-character-per-argument spec. The letters have fixed meanings: i for input and I for optional input, o for output and O for optional output, p for a point and P for an optional point passing two values, s for a string flag and S for an optional string flag, d for a dash as used in names like LINE, and v for a varptr as used in GET and PUT, which passes a buffer and an offset.

Putting the spec together produces a binding key that the interpreter resolves by name. The README's example defines a statement named foo taking a point, an optional input and a string flag:

js
var bindings = GraphicsBindings(canvas);
bindings.statement_foo_pIS = function(x, y, color, style) {
  // x and y: are always available
  // color: might be undefined
  // style: might be undefined and is a literal string
};
basic.Basic(
`
foo (10, 20), 1, dashed
`);

The convention is legible and easy to extend, which is a genuine strength. It is also stringly typed, and the README gives no guidance on how the interpreter reports an argument count mismatch, so a caller that passes the wrong shape will fail at the boundary rather than at a checked signature.

The project is a historical preservation effort, not a general language

The README explains why the project exists, and the explanation sets the scope. The immediate trigger was Ed Thelen's Nike Hercules simulator, which had been written in BASIC and later ported to an unknown version of FreeBASIC. The original distribution included a Windows executable, which made it awkward to show how a historical program actually behaved. Since whole-system emulators that run in the browser do exist, the first goal was to get that one program running directly on the web without booting an entire emulated system.

From there, the stated milestone was DONKEY.BAS, and the README names GORILLA.BAS and NIBBLES.BAS as a current focus. The example list matches that history: the DONKEY.BAS example, a polar graph drawn with trig functions, primes below 3000, a GET and PUT test, a live editor built on Ace, and small drawing demos for circles and lines. Example files in the repository also cover mouse input, a key tester, fonts, a paint example, a screen test and an ESM example.

That origin is useful context for a decision. The project's aim is to run historic BASIC programs faithfully, and its feature growth follows those programs. A team wanting a general-purpose BASIC for new work will find the feature list thin and the extension guidance marked unstable.

Where the gaps are: no releases, a partial test suite, and a licensing check on your side

Three practical limits are visible in the project files.

First, the repository has no GitHub releases, so there is no tagged upgrade path with release notes to read. The npm package version in package.json is 1.0.2, and the last push was on 2026-10-18, so the code is moving, but you are tracking a single main branch rather than a sequence of published versions.

Second, the test suite is described as work in progress, and the README gives the command to run it:

bash
./tests/run-tests.sh

The package manifest points its own test script at ./test/run-tests.sh, so the directory is named test at the top level of the repository while the README refers to tests. Run whichever one matches your checkout, and expect gaps.

Third, licensing is a contributor obligation, not just a label. The project is Apache-2.0, and the README states that every file containing source code must include the copyright and license information, including any JavaScript or CSS served to browsers, so that well-meaning people avoid accidental copying that does not comply. If you extend wwwBASIC with your own statements, that header requirement applies to your files too. The Apache-2.0 grant is permissive for use, including commercial use, with the notice conditions attached.

Editorial conclusion

wwwBASIC suits a team that wants to publish a small BASIC program on a web page, port a historical listing, or teach BASIC without installing anything, and it does not suit a team that needs a supported, stable extension API or a production language with a maintained test suite. Before adopting it, check that the features your program uses are in the short list the README gives, confirm the ./tests/run-tests.sh suite passes on your machine, and treat the external bindings mechanism as experimental, since the README calls it semi-unstable.

Frequently asked questions

How do I run a BASIC program in the browser with wwwBASIC?

Include https://google.github.io/wwwbasic/wwwbasic.js in your page and put the program in a script tag with the type attribute set to text/basic, which wwwBASIC processes by default. The README's example does exactly this with a PRINT statement and a FOR loop.

Can I use wwwBASIC from Node.js instead of a browser page?

Yes. Install it with npm install -S wwwbasic or clone the repository, then require the module and pass your program text to basic.Basic. An ESM import is also available from wwwbasic.mjs.

How do I add my own statement to wwwBASIC?

Follow the kind_name_arguments naming convention, where kind is statement or call and the argument letters are i, o, p, s, d and v. The README's example defines bindings.statement_foo_pIS and then calls foo (10, 20), 1, dashed from BASIC source.

Which graphics and input features does wwwBASIC support?

The README lists graphics with 24-bit color, PSET, LINE and CIRCLE, plus input through INKEY$ and GETMOUSE. Canvas bindings come from basic.GraphicsBindings(canvas) and default console bindings from basic.ConsoleBindings().

Is the wwwBASIC external bindings API stable?

The README states that external bindings are currently considered a semi-unstable feature and should be used with caution. The foundational bindings are PutCh(ch), PutCh(undefined) to flush, and Halt() to print a final message at END.

Official sources

  1. google/wwwbasic on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/google-wwwbasic.svg)](https://hysenlabs.com/projects/google-wwwbasic)

Was this useful?