> ## Documentation Index > Fetch the complete documentation index at: https://bunny.net/docs/llms.txt > Use this file to discover all available pages before exploring further. # Go > Get started with Bunny Database and Go using the libSQL client In this Go quickstart you will learn how to: * Retrieve database credentials * Install the libSQL client * Connect to a remote Bunny Database * Execute a query using SQL ## Quickstart **1. Retrieve database credentials** You will need an existing database to continue. If you don't have one, [create one](https://bunny.net/docs/database/quickstart.md). Navigate to **Dashboard > Edge Platform > Database > \[Select Database] > Access** to find your database URL and generate an access token. > [!NOTE] > > You should store these as environment variables to keep them secure. **2. Install libsql-client-go** Install the libSQL client package: ```bash theme={null} go get github.com/tursodatabase/libsql-client-go/libsql ``` **3. Initialize a new client** Create a database connection with your database URL and auth token: ```go theme={null} package main import ( "database/sql" "fmt" "os" _ "github.com/tursodatabase/libsql-client-go/libsql" ) func main() { url := fmt.Sprintf("%s?authToken=%s", os.Getenv("BUNNY_DATABASE_URL"), os.Getenv("BUNNY_DATABASE_AUTH_TOKEN"), ) db, err := sql.Open("libsql", url) if err != nil { fmt.Fprintf(os.Stderr, "failed to open db %s: %s", url, err) os.Exit(1) } defer db.Close() } ``` **4. Execute a query using SQL** You can execute a SQL query against your database using `Query()` for reads or `Exec()` for writes: ```go theme={null} rows, err := db.Query("SELECT * FROM users") if err != nil { fmt.Fprintf(os.Stderr, "failed to execute query: %v\n", err) os.Exit(1) } defer rows.Close() for rows.Next() { var id int var name string if err := rows.Scan(&id, &name); err != nil { fmt.Fprintf(os.Stderr, "failed to scan row: %v\n", err) os.Exit(1) } fmt.Printf("id: %d, name: %s\n", id, name) } if err := rows.Err(); err != nil { fmt.Fprintf(os.Stderr, "error during iteration: %v\n", err) os.Exit(1) } ``` If you need to use placeholders for values, you can do that: ```go Positional theme={null} rows, err := db.Query("SELECT * FROM users WHERE id = ?", 1) ``` ```go Named theme={null} rows, err := db.Query("SELECT * FROM users WHERE id = :id", sql.Named("id", 1)) ``` ## Placeholders libSQL supports the use of positional and named placeholders within SQL statements: ```go Positional theme={null} rows, err := db.Query("SELECT * FROM users WHERE id = ?", 1) ``` ```go Named theme={null} rows, err := db.Query("SELECT * FROM users WHERE id = :id", sql.Named("id", 1)) ``` > [!NOTE] > > libSQL supports the same named placeholder characters as SQLite — `:`, `@` and > `$`. ## Executing Writes Use `Exec()` for INSERT, UPDATE, and DELETE statements: ```go theme={null} result, err := db.Exec("INSERT INTO users (name) VALUES (?)", "Kit") if err != nil { fmt.Fprintf(os.Stderr, "failed to insert: %v\n", err) os.Exit(1) } rowsAffected, _ := result.RowsAffected() lastInsertId, _ := result.LastInsertId() fmt.Printf("rows affected: %d, last insert id: %d\n", rowsAffected, lastInsertId) ``` ## Transactions You can use transactions to execute multiple statements atomically: ```go theme={null} tx, err := db.Begin() if err != nil { fmt.Fprintf(os.Stderr, "failed to begin transaction: %v\n", err) os.Exit(1) } _, err = tx.Exec("INSERT INTO users (name) VALUES (?)", "Kit") if err != nil { tx.Rollback() fmt.Fprintf(os.Stderr, "failed to insert: %v\n", err) os.Exit(1) } _, err = tx.Exec("INSERT INTO users (name) VALUES (?)", "Sam") if err != nil { tx.Rollback() fmt.Fprintf(os.Stderr, "failed to insert: %v\n", err) os.Exit(1) } if err := tx.Commit(); err != nil { fmt.Fprintf(os.Stderr, "failed to commit: %v\n", err) os.Exit(1) } ``` ## Prepared Statements For repeated queries, you can use prepared statements for better performance: ```go theme={null} stmt, err := db.Prepare("SELECT * FROM users WHERE id = ?") if err != nil { fmt.Fprintf(os.Stderr, "failed to prepare statement: %v\n", err) os.Exit(1) } defer stmt.Close() rows, err := stmt.Query(1) if err != nil { fmt.Fprintf(os.Stderr, "failed to execute query: %v\n", err) os.Exit(1) } defer rows.Close() ``` ## Context Support The libSQL client supports Go's context for timeout and cancellation: ```go theme={null} ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() rows, err := db.QueryContext(ctx, "SELECT * FROM users") if err != nil { fmt.Fprintf(os.Stderr, "failed to execute query: %v\n", err) os.Exit(1) } defer rows.Close() ``` This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.