{"id":29130676,"url":"https://github.com/aperturerobotics/goscript","last_synced_at":"2026-01-17T00:53:34.088Z","repository":{"id":152080483,"uuid":"86519684","full_name":"aperturerobotics/goscript","owner":"aperturerobotics","description":"Go to TypeScript transpiler","archived":false,"fork":false,"pushed_at":"2025-06-27T06:10:24.000Z","size":2606,"stargazers_count":14,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-27T09:15:29.185Z","etag":null,"topics":["compiler","go","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aperturerobotics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-03-29T00:10:35.000Z","updated_at":"2025-06-23T20:49:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"d073d18a-9af7-4bbe-9d21-866c5fd0cf58","html_url":"https://github.com/aperturerobotics/goscript","commit_stats":null,"previous_names":["aperturerobotics/goscript"],"tags_count":52,"template":false,"template_full_name":null,"purl":"pkg:github/aperturerobotics/goscript","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperturerobotics%2Fgoscript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperturerobotics%2Fgoscript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperturerobotics%2Fgoscript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperturerobotics%2Fgoscript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aperturerobotics","download_url":"https://codeload.github.com/aperturerobotics/goscript/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aperturerobotics%2Fgoscript/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262710149,"owners_count":23351943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler","go","typescript"],"created_at":"2025-06-30T04:31:35.363Z","updated_at":"2026-01-17T00:53:34.068Z","avatar_url":"https://github.com/aperturerobotics.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoScript\n\n[![GoDoc Widget]][GoDoc] [![Go Report Card Widget]][Go Report Card] [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/aperturerobotics/goscript)\n\n[GoDoc]: https://godoc.org/github.com/aperturerobotics/goscript\n[GoDoc Widget]: https://godoc.org/github.com/aperturerobotics/goscript?status.svg\n[Go Report Card Widget]: https://goreportcard.com/badge/github.com/aperturerobotics/goscript\n[Go Report Card]: https://goreportcard.com/report/github.com/aperturerobotics/goscript\n\n## What is GoScript?\n\nGoScript 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.\n\n\u003e 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.\n\u003e\n\u003e \u0026mdash; [nevkontakte](https://gophers.slack.com/archives/C039C0R2T/p1745870396945719), developer of [GopherJS](https://github.com/gopherjs/gopherjs)\n\n### 🎯 Why GoScript?\n\nWrite once, run everywhere. Share your Go algorithms, business logic, and data structures seamlessly between your backend and frontend without maintaining two codebases.\n\n**Use cases:**\n\n- Sharing business logic between Go services and web apps\n- Porting Go algorithms to run in browsers\n- Building TypeScript libraries from existing Go code\n\nGo 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.\n\n**✅ What works:**\n\n- Structs, interfaces, methods, and functions with full value semantics\n- Channels and goroutines (translated to async/await with function coloring)\n- Pointers and addressability (via VarRef system)\n- Slices, maps, and built-in types\n- Control flow (if, for, switch, select, range, defer, etc.)\n- Type assertions and interface implementations\n- Closures and anonymous functions\n- Generics\n- Reflection\n- Encoding: encoding/json\n- Most of the standard library\n\n**🚧 In progress:**\n\n- Reflection edge cases\n- Full standard library coverage\n- Various other edge cases (see GitHub issues)\n\n**Important Notes**\n\n- Uses JavaScript `number` type (64-bit float, not Go's int types)\n- No pointer arithmetic (`uintptr`) or `unsafe` package\n- No complex numbers\n\n📖 **Learn more:** [Design document](./design/DESIGN.md) | [Architecture explainer](./docs/explainer.md) | [Compliance tests](./tests/README.md)\n\n🐛 **Found an issue?** Please [open an issue](https://github.com/aperturerobotics/goscript/issues).\n\n## 🚀 Try It\n\n### Prerequisites\n\nGoScript requires [Bun](https://bun.sh) to be installed for running compliance tests:\n\n```bash\n# Install Bun\ncurl -fsSL https://bun.sh/install | bash\n```\n\n### Installation\n\n**Option 1: Go Install**\n\n```bash\ngo install github.com/aperturerobotics/goscript/cmd/goscript@latest\n```\n\n**Option 2: NPM** (if available)\n\n```bash\nnpm install -g goscript\n```\n\n### Compilation\n\n```bash\n# Try compiling your Go package to TypeScript\ngoscript compile --package . --output ./dist\n```\n\n## 📦 Using Generated Code in Your Project\n\nAfter compiling your Go code to TypeScript, you'll need to set up your project appropriately.\n\n### TypeScript Configuration\n\nCreate or update your `tsconfig.json` with these settings:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": [\"ES2022\", \"esnext.disposable\", \"dom\"],\n    \"baseUrl\": \"./\",\n    \"paths\": {\n      \"@goscript/*\": [\"./path/to/generated/output/@goscript/*\"]\n    },\n    \"allowSyntheticDefaultImports\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true\n  }\n}\n```\n\n**Important requirements:**\n\n- **`target: \"ES2022\"` or newer** - Required for `Disposable` and other features\n- **`lib: [\"esnext.disposable\"]`** - Enables TypeScript's disposable types for resource management\n- **`baseUrl` and `paths`** - Allows TypeScript to resolve `@goscript/*` imports\n- **`moduleResolution: \"bundler\"`** - Recommended for modern bundlers\n\nYou should be able to use any TypeScript bundler to compile the generated TypeScript.\n\n## 🛠️ Integration \u0026 Usage\n\n### Command Line\n\n```bash\ngoscript compile --package ./my-go-code --output ./dist\n```\n\n**Options:**\n\n- `--package \u003cpath\u003e` - Go package to compile (default: \".\")\n- `--output \u003cdir\u003e` - Output directory for TypeScript files\n\n### Programmatic API\n\n**Go:**\n\n```go\nimport \"github.com/aperturerobotics/goscript/compiler\"\n\nconf := \u0026compiler.Config{OutputPath: \"./dist\"}\ncomp, err := compiler.NewCompiler(conf, logger, nil)\n_, err = comp.CompilePackages(ctx, \"your/package/path\")\n```\n\n**Node.js:**\n\n```typescript\nimport { compile } from 'goscript'\n\nawait compile({\n  pkg: './my-go-package',\n  output: './dist',\n})\n```\n\n### Frontend Frameworks\n\n**React + GoScript:**\n\n```typescript\nimport { NewCalculator } from '@goscript/myapp/calculator'\n\nfunction CalculatorApp() {\n  const [calc] = useState(() =\u003e NewCalculator())\n\n  const handleAdd = () =\u003e {\n    const result = calc.Add(5, 3)\n    setResult(result)\n  }\n\n  return \u003cbutton onClick={handleAdd}\u003eAdd 5 + 3\u003c/button\u003e\n}\n```\n\n**Vue + GoScript:**\n\n```vue\n\u003cscript setup lang=\"ts\"\u003e\nimport { NewUser, FindUserByEmail } from '@goscript/myapp/user'\n\nconst users = ref([NewUser(1, 'Alice', 'alice@example.com')])\n\nconst searchUser = (email: string) =\u003e {\n  return FindUserByEmail(users.value, email)\n}\n\u003c/script\u003e\n```\n\n## 💡 See It In Action\n\nSee the [example/app](./example/app) for a full todo list application using GoScript with tRPC, Drizzle ORM, and React, or [example/simple](./example/simple) for a comprehensive demo of language features.\n\n### Example: User Management\n\n**Go Code** (`user.go`):\n\n```go\npackage main\n\ntype User struct {\n    ID    int    `json:\"id\"`\n    Name  string `json:\"name\"`\n    Email string `json:\"email\"`\n}\n\nfunc (u *User) IsValid() bool {\n    return u.Name != \"\" \u0026\u0026 u.Email != \"\"\n}\n\nfunc NewUser(id int, name, email string) *User {\n    return \u0026User{ID: id, Name: name, Email: email}\n}\n\nfunc FindUserByEmail(users []*User, email string) *User {\n    for _, user := range users {\n        if user.Email == email {\n            return user\n        }\n    }\n    return nil\n}\n```\n\n**Compile it:**\n\n```bash\ngoscript compile --package . --output ./dist\n```\n\n**Generated TypeScript** (`user.gs.ts`):\n\n```typescript\nexport class User {\n  public ID: number = 0\n  public Name: string = ''\n  public Email: string = ''\n\n  public IsValid(): boolean {\n    const u = this\n    return u.Name !== '' \u0026\u0026 u.Email !== ''\n  }\n\n  constructor(init?: Partial\u003cUser\u003e) {\n    if (init) Object.assign(this, init)\n  }\n}\n\nexport function NewUser(id: number, name: string, email: string): User {\n  return new User({ ID: id, Name: name, Email: email })\n}\n\nexport function FindUserByEmail(users: User[], email: string): User | null {\n  for (let user of users) {\n    if (user.Email === email) {\n      return user\n    }\n  }\n  return null\n}\n```\n\n**Use in your frontend:**\n\n```typescript\nimport { NewUser, FindUserByEmail } from '@goscript/myapp/user'\n\n// Same logic, now in TypeScript!\nconst users = [\n  NewUser(1, 'Alice', 'alice@example.com'),\n  NewUser(2, 'Bob', 'bob@example.com'),\n]\n\nconst alice = FindUserByEmail(users, 'alice@example.com')\nconsole.log(alice?.IsValid()) // true\n```\n\n### Example: Async Processing with Channels\n\n**Go Code:**\n\n```go\nfunc ProcessMessages(messages []string) chan string {\n    results := make(chan string, len(messages))\n\n    for _, msg := range messages {\n        go func(m string) {\n            // Simulate processing\n            processed := \"✓ \" + m\n            results \u003c- processed\n        }(msg)\n    }\n\n    return results\n}\n```\n\n**Generated TypeScript:**\n\n```typescript\nexport function ProcessMessages(messages: string[]): $.Channel\u003cstring\u003e {\n  let results = $.makeChannel\u003cstring\u003e(messages.length, '')\n\n  for (let msg of messages) {\n    queueMicrotask(async (m: string) =\u003e {\n      let processed = '✓ ' + m\n      await results.send(processed)\n    })(msg)\n  }\n\n  return results\n}\n```\n\n**Use with async/await:**\n\n```typescript\nimport { ProcessMessages } from '@goscript/myapp/processor'\n\nasync function handleMessages() {\n  const channel = ProcessMessages(['hello', 'world', 'goscript'])\n\n  // Receive processed messages\n  for (let i = 0; i \u003c 3; i++) {\n    const result = await channel.receive()\n    console.log(result) // \"✓ hello\", \"✓ world\", \"✓ goscript\"\n  }\n}\n```\n\n## 🤝 How You Can Help\n\n- Try GoScript on your code and [report issues](https://github.com/aperturerobotics/goscript/issues)\n- Check the [compliance tests](./tests/README.md) for current progress\n- Contribute test cases for edge cases you discover\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faperturerobotics%2Fgoscript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faperturerobotics%2Fgoscript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faperturerobotics%2Fgoscript/lists"}