npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

goscript

v0.0.71

Published

Go to TypeScript transpiler

Readme

GoScript

GoDoc Widget Go Report Card Widget Ask DeepWiki

What is GoScript?

GoScript is an experimental Go to TypeScript compiler that translates Go code to TypeScript at the AST level. The goal is to enable sharing algorithms and business logic between Go backends and TypeScript frontends.

Right now goscript looks pretty cool if you problem is "I want this self-sufficient algorithm be available in Go and JS runtimes". gopherjs's ambition, however, has always been "any valid Go program can run in a browser". There is a lot that goes on in gopherjs that is necessary for supporting the standard library, which goes beyond cross-language translation.

nevkontakte, developer of GopherJS

🎯 Why GoScript?

Write once, run everywhere. Share your Go algorithms, business logic, and data structures seamlessly between your backend and frontend without maintaining two codebases.

Use cases:

  • Sharing business logic between Go services and web apps
  • Porting Go algorithms to run in browsers
  • Building TypeScript libraries from existing Go code

Go has powerful concurrency support and an excellent standard library. GoScript brings these capabilities to TypeScript with as simple and readable of a translation as possible.

✅ What works:

  • Structs, interfaces, methods, and functions with full value semantics
  • Channels and goroutines (translated to async/await with function coloring)
  • Pointers and addressability (via VarRef system)
  • Slices, maps, and built-in types
  • Control flow (if, for, switch, select, range, defer, etc.)
  • Type assertions and interface implementations
  • Closures and anonymous functions

🚧 In progress:

  • Reflection support
  • Standard library coverage
  • Generics

Known limitations:

  • Uses JavaScript number type (64-bit float, not Go's int types)
  • No pointer arithmetic (uintptr) or unsafe package
  • No complex numbers

📖 Learn more: Design document | Architecture explainer | Compliance tests

🐛 Found an issue? Please open an issue.

🚀 Try It

Prerequisites

GoScript requires Bun to be installed for running compliance tests:

# Install Bun
curl -fsSL https://bun.sh/install | bash

Installation

Option 1: Go Install

go install github.com/aperturerobotics/goscript/cmd/goscript@latest

Option 2: NPM (if available)

npm install -g goscript

Compilation

# Try compiling your Go package to TypeScript
goscript compile --package . --output ./dist

📦 Using Generated Code in Your Project

After compiling your Go code to TypeScript, you'll need to set up your project appropriately.

TypeScript Configuration

Create or update your tsconfig.json with these settings:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "lib": ["ES2022", "esnext.disposable", "dom"],
    "baseUrl": "./",
    "paths": {
      "@goscript/*": ["./path/to/generated/output/@goscript/*"]
    },
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true
  }
}

Important requirements:

  • target: "ES2022" or newer - Required for Disposable and other features
  • lib: ["esnext.disposable"] - Enables TypeScript's disposable types for resource management
  • baseUrl and paths - Allows TypeScript to resolve @goscript/* imports
  • moduleResolution: "bundler" - Recommended for modern bundlers

You should be able to use any TypeScript bundler to compile the generated TypeScript.

🛠️ Integration & Usage

Command Line

goscript compile --package ./my-go-code --output ./dist

Options:

  • --package <path> - Go package to compile (default: ".")
  • --output <dir> - Output directory for TypeScript files

Programmatic API

Go:

import "github.com/aperturerobotics/goscript/compiler"

conf := &compiler.Config{OutputPath: "./dist"}
comp, err := compiler.NewCompiler(conf, logger, nil)
_, err = comp.CompilePackages(ctx, "your/package/path")

Node.js:

import { compile } from 'goscript'

await compile({
  pkg: './my-go-package',
  output: './dist',
})

Frontend Frameworks

React + GoScript:

import { NewCalculator } from '@goscript/myapp/calculator'

function CalculatorApp() {
  const [calc] = useState(() => NewCalculator())

  const handleAdd = () => {
    const result = calc.Add(5, 3)
    setResult(result)
  }

  return <button onClick={handleAdd}>Add 5 + 3</button>
}

Vue + GoScript:

<script setup lang="ts">
import { NewUser, FindUserByEmail } from '@goscript/myapp/user'

const users = ref([NewUser(1, 'Alice', '[email protected]')])

const searchUser = (email: string) => {
  return FindUserByEmail(users.value, email)
}
</script>

💡 See It In Action

See the example/app for a full todo list application using GoScript with tRPC, Drizzle ORM, and React, or example/simple for a comprehensive demo of language features.

Example: User Management

Go Code (user.go):

package main

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

func (u *User) IsValid() bool {
    return u.Name != "" && u.Email != ""
}

func NewUser(id int, name, email string) *User {
    return &User{ID: id, Name: name, Email: email}
}

func FindUserByEmail(users []*User, email string) *User {
    for _, user := range users {
        if user.Email == email {
            return user
        }
    }
    return nil
}

Compile it:

goscript compile --package . --output ./dist

Generated TypeScript (user.gs.ts):

export class User {
  public ID: number = 0
  public Name: string = ''
  public Email: string = ''

  public IsValid(): boolean {
    const u = this
    return u.Name !== '' && u.Email !== ''
  }

  constructor(init?: Partial<User>) {
    if (init) Object.assign(this, init)
  }
}

export function NewUser(id: number, name: string, email: string): User {
  return new User({ ID: id, Name: name, Email: email })
}

export function FindUserByEmail(users: User[], email: string): User | null {
  for (let user of users) {
    if (user.Email === email) {
      return user
    }
  }
  return null
}

Use in your frontend:

import { NewUser, FindUserByEmail } from '@goscript/myapp/user'

// Same logic, now in TypeScript!
const users = [
  NewUser(1, 'Alice', '[email protected]'),
  NewUser(2, 'Bob', '[email protected]'),
]

const alice = FindUserByEmail(users, '[email protected]')
console.log(alice?.IsValid()) // true

Example: Async Processing with Channels

Go Code:

func ProcessMessages(messages []string) chan string {
    results := make(chan string, len(messages))

    for _, msg := range messages {
        go func(m string) {
            // Simulate processing
            processed := "✓ " + m
            results <- processed
        }(msg)
    }

    return results
}

Generated TypeScript:

export function ProcessMessages(messages: string[]): $.Channel<string> {
  let results = $.makeChannel<string>(messages.length, '')

  for (let msg of messages) {
    queueMicrotask(async (m: string) => {
      let processed = '✓ ' + m
      await results.send(processed)
    })(msg)
  }

  return results
}

Use with async/await:

import { ProcessMessages } from '@goscript/myapp/processor'

async function handleMessages() {
  const channel = ProcessMessages(['hello', 'world', 'goscript'])

  // Receive processed messages
  for (let i = 0; i < 3; i++) {
    const result = await channel.receive()
    console.log(result) // "✓ hello", "✓ world", "✓ goscript"
  }
}

🤝 How You Can Help

License

MIT