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

@sylphx/synth-go

v0.3.1

Published

Go parser using Synth's universal AST - WASM-based, works everywhere

Readme

@sylphx/synth-go

Go parser using Synth's universal AST. Conversion layer over tree-sitter-go.

Features

  • Strategic Dependency - Uses tree-sitter-go (battle-tested Go parser)
  • 🚀 Full Go Support - All Go language features
  • 🎯 Universal AST - Converts tree-sitter CST to Synth's language-agnostic format
  • 🔌 Plugin System - Transform AST with sync/async plugins
  • 📦 Battle-Tested - tree-sitter powers VS Code, Atom, and many other editors

Installation

npm install @sylphx/synth-go

Usage

Quick Start

import { parse } from '@sylphx/synth-go'

const go = `
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
`

const tree = parse(go)
console.log(tree.nodes[tree.root])

Parser API

import { GoParser, createParser, parse, parseAsync } from '@sylphx/synth-go'

// Standalone function (recommended)
const tree = parse('package main\n\nvar x = 42')

// Async parsing (for plugins)
const tree = await parseAsync('package main\n\nvar x = 42')

// Class instance
const parser = new GoParser()
const tree = parser.parse('package main\n\nvar x = 42')

// Factory function
const parser = createParser()
const tree = parser.parse('package main\n\nvar x = 42')

Plugin System

import { parse, type Tree } from '@sylphx/synth-go'

// Sync plugin
const myPlugin = {
  name: 'my-plugin',
  transform(tree: Tree) {
    // Modify tree
    return tree
  }
}

const tree = parse(goSource, { plugins: [myPlugin] })

// Async plugin
const asyncPlugin = {
  name: 'async-plugin',
  async transform(tree: Tree) {
    // Async modifications
    return tree
  }
}

const tree = await parseAsync(goSource, { plugins: [asyncPlugin] })

AST Structure

The parser generates a universal Synth AST by converting tree-sitter's concrete syntax tree. Each node includes:

Node Structure

{
  type: 'FunctionDeclaration',  // Mapped from tree-sitter type
  parent: NodeId,
  children: [NodeId],
  span: {
    start: { offset, line, column },
    end: { offset, line, column }
  },
  data: {
    text: 'func main()...',     // Original source text
    isNamed: true,                // tree-sitter named node
    originalType: 'function_declaration'  // Original tree-sitter type
  }
}

Supported Go Features

Data Types

  • ✅ Strings (raw, interpreted)
  • ✅ Integers (int, int8, int16, int32, int64)
  • ✅ Floats (float32, float64)
  • ✅ Booleans (true, false)
  • ✅ Arrays [5]int{1, 2, 3, 4, 5}
  • ✅ Slices []int{1, 2, 3}
  • ✅ Maps map[string]int{"a": 1}
  • ✅ Structs
  • ✅ Pointers
  • ✅ Interfaces

Control Flow

  • if/else statements
  • for loops (traditional, range, infinite)
  • switch statements (expression and type)
  • select for channel operations
  • defer statements
  • goto and labels

Functions

  • ✅ Function declarations
  • ✅ Parameters and return values
  • ✅ Multiple return values
  • ✅ Named return values
  • ✅ Variadic functions func sum(nums ...int)
  • ✅ Anonymous functions and closures
  • ✅ Methods (value and pointer receivers)

Types and Interfaces

  • ✅ Type definitions type MyInt int
  • ✅ Struct definitions
  • ✅ Interface definitions
  • ✅ Empty interface interface{}
  • ✅ Type assertions
  • ✅ Type switches
  • ✅ Embedded types

Concurrency

  • ✅ Goroutines go func()
  • ✅ Channels make(chan int)
  • ✅ Channel operations <-ch, ch <-
  • ✅ Buffered channels
  • ✅ Select statements
  • ✅ Mutex and WaitGroup

Packages

  • ✅ Package declaration package main
  • ✅ Import statements
  • ✅ Import aliases import f "fmt"
  • ✅ Dot imports import . "math"
  • ✅ Blank imports import _ "image/png"

Error Handling

  • ✅ Error returns
  • panic and recover
  • defer for cleanup

Examples

HTTP Server

const go = `
package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}
`

const tree = parse(go)

Concurrent Worker Pool

const go = `
package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    for job := range jobs {
        fmt.Printf("Worker %d processing job %d\\n", id, job)
        time.Sleep(time.Second)
        results <- job * 2
    }
}

func main() {
    const numJobs = 5
    jobs := make(chan int, numJobs)
    results := make(chan int, numJobs)
    var wg sync.WaitGroup

    // Start workers
    for w := 1; w <= 3; w++ {
        wg.Add(1)
        go worker(w, jobs, results, &wg)
    }

    // Send jobs
    for j := 1; j <= numJobs; j++ {
        jobs <- j
    }
    close(jobs)

    // Wait and collect results
    go func() {
        wg.Wait()
        close(results)
    }()

    for result := range results {
        fmt.Println("Result:", result)
    }
}
`

const tree = parse(go)

REST API with Struct Tags

const go = `
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

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

type UserResponse struct {
    Success bool   \`json:"success"\`
    Data    User   \`json:"data,omitempty"\`
    Error   string \`json:"error,omitempty"\`
}

func getUser(w http.ResponseWriter, r *http.Request) {
    user := User{
        ID:        1,
        Name:      "John Doe",
        Email:     "[email protected]",
        CreatedAt: "2024-01-01T00:00:00Z",
    }

    response := UserResponse{
        Success: true,
        Data:    user,
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(response)
}

func main() {
    http.HandleFunc("/api/user", getUser)
    log.Fatal(http.ListenAndServe(":8080", nil))
}
`

const tree = parse(go)

Generic Data Structures (Go 1.18+)

const go = `
package main

import "fmt"

type Stack[T any] struct {
    items []T
}

func (s *Stack[T]) Push(item T) {
    s.items = append(s.items, item)
}

func (s *Stack[T]) Pop() (T, bool) {
    var zero T
    if len(s.items) == 0 {
        return zero, false
    }
    item := s.items[len(s.items)-1]
    s.items = s.items[:len(s.items)-1]
    return item, true
}

func main() {
    intStack := Stack[int]{}
    intStack.Push(1)
    intStack.Push(2)
    intStack.Push(3)

    if val, ok := intStack.Pop(); ok {
        fmt.Println("Popped:", val)
    }

    stringStack := Stack[string]{}
    stringStack.Push("hello")
    stringStack.Push("world")
}
`

const tree = parse(go)

Database Operations

const go = `
package main

import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/lib/pq"
)

type User struct {
    ID    int
    Name  string
    Email string
}

func getUsers(db *sql.DB) ([]User, error) {
    rows, err := db.Query("SELECT id, name, email FROM users")
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var users []User
    for rows.Next() {
        var u User
        if err := rows.Scan(&u.ID, &u.Name, &u.Email); err != nil {
            return nil, err
        }
        users = append(users, u)
    }

    return users, rows.Err()
}

func createUser(db *sql.DB, name, email string) (int, error) {
    var id int
    err := db.QueryRow(
        "INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id",
        name, email,
    ).Scan(&id)

    return id, err
}

func main() {
    connStr := "user=postgres dbname=mydb sslmode=disable"
    db, err := sql.Open("postgres", connStr)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    users, err := getUsers(db)
    if err != nil {
        log.Fatal(err)
    }

    for _, user := range users {
        fmt.Printf("%d: %s (%s)\\n", user.ID, user.Name, user.Email)
    }
}
`

const tree = parse(go)

Performance

Leverages tree-sitter's high-performance parsing:

  • Fast incremental parsing
  • Error recovery
  • Battle-tested in production editors
  • Efficient memory usage

Development Philosophy

This package uses a strategic dependency approach:

  • Third-party parser: tree-sitter-go (used by VS Code, Atom, GitHub)
  • Our conversion layer: tree-sitter CST → Synth universal AST
  • Our value: Universal format, cross-language tools, plugin system

Why tree-sitter?

  • ❌ Writing Go parser: 150+ hours, complex grammar, spec updates
  • ✅ Using tree-sitter: Battle-tested, incremental parsing, error recovery
  • Our focus: Universal AST format, transformations, cross-language operations

Use Cases

  • Code analysis: Analyze Go codebases
  • Linting: Build custom Go linters
  • Documentation: Extract comments and signatures
  • Code generation: Transform Go AST
  • Migration tools: Refactor Go code
  • Static analysis: Complexity analysis, dependency graphs
  • Cross-language tools: Analyze Go + JavaScript + Python together

Comparison with go/ast

Unlike Go's built-in go/ast package, @sylphx/synth-go:

  • Works in JavaScript/TypeScript environments
  • Uses universal AST format compatible with other languages
  • Provides plugin system for transformations
  • Integrates with other Synth parsers
  • Suitable for multi-language tooling

License

MIT


Note: This package uses tree-sitter-go for parsing. See tree-sitter-go for parser details.