この記事はAI(Codex)による執筆をベースにしています。
GitHubリポジトリを解析させた上で、
構成・ポイントを指示し、記事を生成しています。
内容の最終確認・調整は投稿主が行っています。
試験的な取り組みのため、表現や粒度に粗さがある可能性があります。
概要
Wails で作ったデスクトップアプリに SQLite を導入し、実際に DB ファイルが出力されるところまで確認しました。
対象リポジトリは以下です。
今回は「まず SQLite に接続できる状態を作る」ことをゴールにして、Wails の起動時にテーブル作成とサンプルデータ投入まで行っています。
2026年3月20日にこの実装を確認したところ、./device.db が生成され、devices テーブルに 1 件入る状態まで確認できました。
技術スタック
- Windows 11
- Go 1.25.1 windows/amd64
-
go.modの Go バージョン指定:go 1.23 - Node.js v24.6.0
- npm 11.6.0
- Wails v2.11.0
- React テンプレート
- SQLite
- SQLite ドライバ:
github.com/mattn/go-sqlite3 v1.14.37
リポジトリの go.mod では、SQLite 関連の依存が次のように追加されています。
module forge-wake-control
go 1.23
require (
github.com/mattn/go-sqlite3 v1.14.37
github.com/wailsapp/wails/v2 v2.11.0
)
実装手順
1. Wails の開発環境を入れる
まずは Wails の CLI をインストールします。
go install github.com/wailsapp/wails/v2/cmd/wails@latest
今回の作業ログでは、2026年3月19日時点で v2.11.0 が入っていました。実際に手元でも次のように確認できました。
wails version
v2.11.0
2. React テンプレートでプロジェクトを作る
Wails の React テンプレートでプロジェクトを作成します。
wails init -n forge-wake-control -t react
このあとに作られた main.go では、Wails アプリの起動処理が定義されています。後で SQLite 初期化をつなぐのはこの起動フックです。
func main() {
app := NewApp()
err := wails.Run(&options.App{
Title: "forge-wake-control",
Width: 1024,
Height: 768,
AssetServer: &assetserver.Options{
Assets: assets,
},
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
OnStartup: app.startup,
Bind: []interface{}{
app,
},
})
if err != nil {
println("Error:", err.Error())
}
}
OnStartup: app.startup になっているので、アプリ起動時に startup() が呼ばれます。
3. SQLite ドライバを追加する
次に SQLite ドライバを追加します。
go get github.com/mattn/go-sqlite3
今回使っているのは Go 標準の database/sql と go-sqlite3 の組み合わせです。
Wails 専用の特殊な書き方はなく、Go アプリとして普通に DB 接続を作れます。
4. Windows では GCC を用意する
github.com/mattn/go-sqlite3 は CGO を使うので、Windows では GCC が必要です。
今回は MSYS2 を使ってセットアップしています。
pacman -Syu
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
その後、次のディレクトリに PATH を通しています。
C:\msys64\ucrt64\bin
手元でも GCC は次のように確認できました。
gcc --version
gcc.exe (Rev13, Built by MSYS2 project) 15.2.0
5. SQLite 接続処理を db/sqlite.go に切り出す
実際のリポジトリでは、接続処理を db/sqlite.go に切り出しています。
package db
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
func Connect() (*sql.DB, error) {
// TODO パス指定
db, err := sql.Open("sqlite3", "./device.db")
if err != nil {
return nil, err
}
if err := db.Ping(); err != nil {
return nil, err
}
return db, nil
}
ポイントは次の 2 つです。
-
_ "github.com/mattn/go-sqlite3"の blank import で SQLite ドライバを登録している -
sql.Open("sqlite3", "./device.db")で、カレントディレクトリ配下にdevice.dbを作るようにしている
sql.Open() だけだと接続確認が遅延することがあるので、Ping() まで呼んでおくと起動時に失敗を検知しやすいです。
6. startup() でテーブル作成と初期データ投入を行う
次に、Wails の起動時に SQLite を初期化するコードを app.go に追加します。
package main
import (
"context"
"database/sql"
"fmt"
"forge-wake-control/db"
)
type App struct {
ctx context.Context
db *sql.DB
}
func NewApp() *App {
return &App{}
}
func (a *App) startup(ctx context.Context) {
conn, err := db.Connect()
if err != nil {
fmt.Println("DB init error:", err)
return
}
_, err = conn.Exec(`CREATE TABLE IF NOT EXISTS devices (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL
)`)
if err != nil {
fmt.Println("DB table creation error:", err)
return
}
_, err = conn.Exec(`INSERT INTO devices (name) VALUES (?)`, "Sample Device")
if err != nil {
fmt.Println("DB record insertion error:", err)
return
}
a.db = conn
a.ctx = ctx
}
func (a *App) shutdown(ctx context.Context) {
if a.db != nil {
a.db.Close()
}
}
流れはかなりシンプルです。
-
db.Connect()で SQLite に接続する -
CREATE TABLE IF NOT EXISTSでdevicesテーブルを作る - サンプルとして
Sample Deviceを 1 件入れる -
shutdown()で DB を閉じる
CREATE TABLE IF NOT EXISTS を使っているので、すでにテーブルがある状態で再起動してもテーブル作成では落ちません。
7. 起動して device.db が出ることを確認する
ここまでできたら Wails を起動します。
wails dev
今回の実装では startup() の中で sql.Open("sqlite3", "./device.db") を呼んでいるので、起動時に device.db が作成されます。
今回の確認では、startup() 実行後に repo_src/device.db が生成され、devices テーブルの件数が 1 になるところまで確認できました。
まずは「Wails から SQLite を開ける」「ファイルが実際に作られる」という最初の確認としては十分です。
解決方法
今回の解決方法は、かなり素直でした。
-
go get github.com/mattn/go-sqlite3で SQLite ドライバを追加する - Windows では MSYS2 で GCC を入れて、
C:\msys64\ucrt64\binに PATH を通す - Wails の
OnStartupからdb.Connect()を呼び、起動時にテーブル作成まで済ませる
コードとして見ると、実質的にはこの組み合わせで成立しています。
func Connect() (*sql.DB, error) {
db, err := sql.Open("sqlite3", "./device.db")
if err != nil {
return nil, err
}
if err := db.Ping(); err != nil {
return nil, err
}
return db, nil
}
func (a *App) startup(ctx context.Context) {
conn, err := db.Connect()
if err != nil {
fmt.Println("DB init error:", err)
return
}
_, err = conn.Exec(`CREATE TABLE IF NOT EXISTS devices (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL
)`)
if err != nil {
fmt.Println("DB table creation error:", err)
return
}
_, err = conn.Exec(`INSERT INTO devices (name) VALUES (?)`, "Sample Device")
if err != nil {
fmt.Println("DB record insertion error:", err)
return
}
a.db = conn
a.ctx = ctx
}
大きく詰まったところはなく、Windows では go-sqlite3 のための GCC 準備だけ忘れなければ、その後は Go の DB 初期化処理を足していくだけで進められました。
まとめ
Wails で SQLite を使うときも、Go 側では普段どおり database/sql を使って実装できます。
今回のように startup() で接続、テーブル作成、初期データ投入までまとめてしまうと、まず device.db が生成されるところまでを短く確認できます。
注意点もあります。
-
./device.dbは相対パスなので、将来的には保存場所をきちんと決めたほうがよい - 今の実装だと起動のたびに
Sample Deviceが追加される -
shutdown()でClose()しておくと後から扱いやすい
最初の一歩としては、Wails 側の起動フックに SQLite 初期化をつなぐだけで十分でした。
次はこの上に、一覧取得、追加、更新、削除のメソッドを増やしていけば、Wails から SQLite を使ったデスクトップアプリとして育てていけそうです。