Skip to content

Latest commit

 

History

History
307 lines (223 loc) · 6.49 KB

File metadata and controls

307 lines (223 loc) · 6.49 KB

Getting Started

This guide shows how to import GoScript into a larger web project and wire it up correctly.

The short version:

  1. Install the package
  2. Host goscript.pack somewhere your app can fetch it
  3. Import GoScript
  4. Create an initialized instance with GoScript.create()
  5. Call runCode()

What You Need To Host

The npm package gives you the JavaScript runtime and SDK code.

It does not bundle goscript.pack into your app automatically.

You must host the compiler pack yourself, for example at:

  • /assets/goscript.pack
  • /public/goscript.pack
  • a CDN URL you control

Then pass that URL into GoScript with packUrl.

Published download links:

  • Release page: https://github.com/monstercameron/GoScript/releases/tag/demo
  • Direct goscript.pack download: https://github.com/monstercameron/GoScript/releases/download/demo/goscript.pack

If you just need the compiler pack file, use that direct goscript.pack URL, then place the file in your app's public/static assets folder.

Install

npm install goscript

Minimal Browser Example

import GoScript from 'goscript';

const gs = await GoScript.create({
  packUrl: '/assets/goscript.pack',
  stdout: (text) => {
    console.log(text);
  },
  stderr: (error) => {
    console.error(error);
  },
  progress: (percent, message) => {
    console.log(percent, message);
  }
});

await gs.runCode(`
package main

import "fmt"

func main() {
    fmt.Println("Hello from GoScript")
}
`);

Typical UI Wiring

import GoScript from 'goscript';

const outputEl = document.getElementById('output');
const runButton = document.getElementById('run');
const statusEl = document.getElementById('status');
const sourceEl = document.getElementById('source');

const gs = await GoScript.create({
  packUrl: '/assets/goscript.pack',
  stdout: (text) => {
    outputEl.textContent += text;
  },
  stderr: (error) => {
    outputEl.textContent += `Error: ${error}\n`;
  },
  progress: (percent, message) => {
    statusEl.textContent = `${percent}% ${message}`;
  }
});

statusEl.textContent = 'Ready';

runButton.addEventListener('click', async () => {
  outputEl.textContent = '';
  statusEl.textContent = 'Compiling...';

  const resultTuple = await gs.compileAndRun(sourceEl.value);
  if (!resultTuple.success) {
    statusEl.textContent = 'Failed';
    outputEl.textContent += resultTuple.error;
    return;
  }

  statusEl.textContent = `Done in ${resultTuple.compileResult.metadata.compileTime}ms`;
});

Recommended Asset Layout

For most frontend apps:

your-app/
  public/
    goscript.pack
  src/
    main.js

Then:

const gs = new GoScript({
  packUrl: '/goscript.pack'
});

For the smallest obvious API, prefer:

const gs = await GoScript.create({
  packUrl: '/goscript.pack'
});

React Example

import { useEffect, useRef, useState } from 'react';
import GoScript from 'goscript';

const toResult = (promise) => promise.then(
  (value) => [value, null],
  (error) => [null, error]
);

export function GoRunner() {
  const sdkRef = useRef(null);
  const [ready, setReady] = useState(false);
  const [output, setOutput] = useState('');

  useEffect(() => {
    (async () => {
      const [gs, initError] = await toResult(GoScript.create({
        packUrl: '/goscript.pack',
        stdout: (text) => {
          setOutput((current) => current + text);
        }
      }));

      if (initError) {
        setOutput(`Init failed: ${initError.message}`);
        return;
      }

      sdkRef.current = gs;
      setReady(true);
    })();
  }, []);

  async function run() {
    if (!sdkRef.current) {
      return;
    }

    setOutput('');

    const runResult = await sdkRef.current.compileAndRun(`
package main

import "fmt"

func main() {
    fmt.Println("Hello from React")
}
`);
    if (!runResult.success) {
      setOutput(runResult.error);
    }
  }

  return (
    <div>
      <button disabled={!ready} onClick={run}>
        Run
      </button>
      <pre>{output}</pre>
    </div>
  );
}

Vite / Next / Static Site Notes

  • Put goscript.pack in your app's public/static assets folder.
  • Use a same-origin packUrl when possible.
  • Do not rely on client-side fetches from GitHub Releases directly; that usually fails due to CORS.

Good:

packUrl: '/goscript.pack'

Usually bad in-browser:

packUrl: 'https://github.com/owner/repo/releases/download/tag/goscript.pack'

Multiple Source Files

build() and compile() accept either a string or a filename-to-source map.

const result = await gs.build({
  'main.go': `
package main

func main() {
    hello()
}
`,
  'hello.go': `
package main

import "fmt"

func hello() {
    fmt.Println("hello from another file")
}
`
});

await gs.run(result.wasm);

Recommended Public API

For new integrations, start with these methods:

  • GoScript.create(options) - create and initialize in one step
  • gs.runCode(source) - compile and run source code
  • gs.build(source) - compile without running
  • gs.run(wasm) or gs.runWasm(wasm) - run an already-built binary
  • gs.clearCompiledCache(source?) - clear compiled cache for one source input

Older compatibility methods like init(), compile(), and compileAndRun() still exist, but they are no longer the simplest path to start with.

Cache Behavior

GoScript uses two separate caches in the browser:

  • toolchain cache: the downloaded goscript.pack
  • compiled wasm cache: binaries keyed by source hash

If you are integrating into a larger app, you should decide whether to expose controls for:

  • clearing the toolchain cache
  • clearing compiled binaries

Operational Constraints

  • First-time initialization is large because goscript.pack is about 168 MB
  • Compilation is CPU and memory heavy compared to normal browser tasks
  • This package is meant for browser environments with WebAssembly support
  • The output target is js/wasm

Common Mistakes

1. Forgetting packUrl

If your app does not host the pack at the default path, initialization will fail.

const gs = new GoScript({
  packUrl: '/my-custom-path/goscript.pack'
});

2. Hosting the pack behind a bad URL

The browser needs a real binary response, not an HTML error page.

3. Expecting npm install to include the pack

It does not. Host the pack separately.

4. Using server-only code paths

GoScript is designed for browser execution, not Node-side compilation.

Next Reading

  • SDK.md
  • PACK-FORMAT.md