Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 75 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Go Bootstrapper
# BootstrapCLI

**Go Bootstrapper** is a CLI tool that scaffolds production-ready Golang projects — no dependency headaches, no manual setup.
**BootstrapCLI** is a CLI tool that scaffolds production-ready Golang projects — no dependency headaches, no manual setup.
Just run a command and get a fully configured project with linters, routers, and structure ready to code.

* * *
Expand All @@ -18,74 +18,106 @@ Once installed, confirm the installation:

## Quick Start 💨

Create a REST API project using **Gin**:
#### 1. Create a New Project

```
bootstrap new myapp --type=rest --router=gin --port=8080
bootstrap new myapp --type=rest --router=gin --port=8080 --db=postgres
```
- This command scaffolds a production-ready Go project with:
- Standard project structure
- Database configuration
- Router setup
- Makefile and tooling

Create a project with **PostgreSQL** integration:
#### 2. Prepare the Project

```
bootstrap new myapp --type=rest --router=gin --db=postgres
cd myapp && make tidy
```

#### 3. Start Required Services (Database)
```
docker compose up -d
```

Before running ``make run`` make sure that you have running 'db' in docker, running with the same credentials as in .env file.

#### 4. Run the Application

```
make run
```

* * *

## Example Project Structure

```
myapp/
├── Makefile
├── README.md
├── cmd/
│ └── main.go
├── internal/
│ ├── config/
│ │ └── config.go
│ ├── handler/
│ │ └── user_handler.go
│ ├── router/
│ │ └── routes.go
│ └── db/ ← created only if --db flag is passed
│ └── db.go
└── go.mod
├── cmd
│ └── main.go
├── docker-compose.yml
├── go.mod
├── go.sum
├── internal
│ ├── config
│ │ ├── config.go
│ │ └── config_test.go
│ ├── db
│ │ └── database.go
│ ├── handler
│ │ └── user_handler.go
│ ├── model
│ │ ├── registory.go
│ │ └── user_model.go
│ ├── repository
│ │ └── user_repo.go
│ ├── server
│ │ ├── routes.go
│ │ └── server.go
│ └── service
│ └── user_service.go
├── Makefile
├── project.yaml
└── README.md

```

* * *

## CLI Options
### `new`

| Flag | Description | Example |
| --- | --- | --- |
| --type | Type of project (rest, grpc, etc.) | --type=rest |
| --router | Router framework (gin, chi, echo) | --router=gin |
| --port | Application port | --port=8080 |
| --db | Database integration | --db=postgres |
Creates a new project with the specified configuration options.

* * *
### Flags

## Why Go Bootstrapper?
| Flag | Description | Example |
|--------------|-------------------------------------------------|----------------------|
| `--type` | Type of project (e.g., `rest`) | `--type=rest` |
| `--router` | Router framework (`gin`, `chi`, `echo`, `fiber`) | `--router=gin` |
| `--port` | Application port | `--port=8080` |
| `--db` | Database integration | `--db=postgres` |
| `--entities` | Add entities | `--entities=user` |

Developers often waste time repeating setup tasks — creating folders, configuring routers, writing Makefiles, adding linters, etc.

**Go Bootstrapper** automates all that.
You focus on business logic — it handles the rest.
### `apply`
Create a new project using yaml file configurations
| Flag | Description | Example |
|--------------|------------------------------------------------- |----------------------|
| `--yaml` | unique file name for the yaml file | `--yaml=project.yaml`|

It’s like:
**BootstrapCLI** automates all that.
You focus on business logic — it handles the rest.

> `create-react-app`, but for Golang �
> Note: This is my first OSS project, I want to make a CLI tool(maybe webUI) which is not just generator tool which only generate
> go code, but it will help developers to follow best practices, and assist during the project development. In future versions of the project i will add AI which will help developer to assist during their development and help in debugging + fixing error. I am adding AI not to generate code in there project but for assisting purpose only.

* * *

## Roadmap

* Add `--with-auth` flag for JWT + middleware setup
* `add` command to make CLI tool more extensible to generate ``service``, ``handlers``, ``controllers``.
* Commands like ``build``, ``test``, ``dev``, ``fmt`` to make it more developer friendly, ensuring production ready code.
* ``init`` that will be used for letting users to choose their configurations via ``TUI``.

* Add CLI command that let users to write their project description, to generate the project automatically without using flags.
* Command such as ``explain``, ``error`` , ``upgrade`` for the tool to make it progressive CLI tool.
* Add support for ``auth``, ``logging`` , ``observability`` and so on if it make sense.
* Add functionality in which users can switch to other options, for example postgres -> mongodb.

* * *

Expand All @@ -94,12 +126,12 @@ It’s like:
Contributions, feedback, and ideas are welcome!
Feel free to open an issue or PR on [GitHub](https://github.com/upsaurav12/bootstrap).

Consider star the project 🙏
Hope you like this project.

* * *

## License

Licensed under the **MIT License** © 2025 [Saurav Upadhyay](https://github.com/upsaurav12)
Licensed under the **MIT License** © 2026 [Saurav Upadhyay](https://github.com/upsaurav12)

* * *
3 changes: 3 additions & 0 deletions cmd/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ type TemplateData struct {
OtherImports string
UpperEntity []string
ApiGroup func(entity string, get string, lowerentity string) string
IsAPIGroup bool
Get string
FullContext string
ToTheClient string
Expand Down Expand Up @@ -215,6 +216,7 @@ func buildTemplateData(projectName string,
Returnable: frameworkConfig.Returnable,
ReturnKeyword: frameworkConfig.ReturnKeyword,
HTTPHandler: frameworkConfig.HTTPHandler,
IsAPIGroup: frameworkConfig.IsAPIGroup,
Entities: Entities,
// UpperEntity: ,
}
Expand Down Expand Up @@ -246,6 +248,7 @@ func buildTemplateData(projectName string,
ReturnKeyword: frameworkConfig.ReturnKeyword,
HTTPHandler: frameworkConfig.HTTPHandler,
Entities: yamlConfig.Entities,
IsAPIGroup: frameworkConfig.IsAPIGroup,
}
}

Expand Down
22 changes: 12 additions & 10 deletions pkg/framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type FrameworkConfig struct {
ReturnKeyword string
HTTPHandler string
Entities []string
IsAPIGroup bool
}

var FrameworkRegistory = map[string]FrameworkConfig{
Expand All @@ -38,6 +39,7 @@ var FrameworkRegistory = map[string]FrameworkConfig{
Start: "gin.Default()",
OtherImports: `"net/http"`,
FullContext: "c *gin.Context",
IsAPIGroup: true,
ApiGroup: func(entity string, get string, lowerentity string) string {
apiGroup := fmt.Sprintf(`
{
Expand Down Expand Up @@ -80,18 +82,19 @@ var FrameworkRegistory = map[string]FrameworkConfig{
"github.com/go-chi/render"
"net/http"
`,
IsAPIGroup: false,
ApiGroup: func(entity string, get string, lowerentity string) string {
apiGroup := fmt.Sprintf(`
r.Group(func(r chi.Router) {
r.%s("/%s", handler.Get%ss)
r.%s("/%s", %sHandler.Get%ss)
})
`, get, lowerentity, entity)
`, get, lowerentity, lowerentity, entity)

return apiGroup
},
Get: "Get",
FullContext: "w http.ResponseWriter, r *http.Request",
ToTheClient: "json.NewEncoder(w).Encode(",
ToTheClient: "render.JSON(w,r,",
Response: "(w, r,",
ImportRouter: `
"encoding/json"
Expand All @@ -117,17 +120,16 @@ var FrameworkRegistory = map[string]FrameworkConfig{
Router: "*echo.Echo",
Start: "echo.New()",
OtherImports: `"net/http"`,

IsAPIGroup: true,
ApiGroup: func(entity, get, lowerentity string) string {
return fmt.Sprintf(`
api := r.Group("/api/v1")
{
%s := api.Group("/%s")
{
%s.%s("", handler.Get%ss)
%s.%s("", %sHandler.Get%ss)
}
}
`, lowerentity, lowerentity, lowerentity, get, entity)
`, lowerentity, lowerentity, lowerentity, get, lowerentity, entity)
},

Get: "GET",
Expand Down Expand Up @@ -162,17 +164,17 @@ var FrameworkRegistory = map[string]FrameworkConfig{
Router: "*fiber.App",
Start: "fiber.New()",
OtherImports: `"net/http"`,

IsAPIGroup: true,
ApiGroup: func(entity, get, lowerentity string) string {
return fmt.Sprintf(`
api := r.Group("/api/v1")
{
%s := api.Group("/%s")
{
%s.%s("", handler.Get%ss)
%s.%s("", %sHandler.Get%ss)
}
}
`, lowerentity, lowerentity, lowerentity, get, entity)
`, lowerentity, lowerentity, lowerentity, get, lowerentity, entity)
},

Get: "Get",
Expand Down
4 changes: 2 additions & 2 deletions project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ project:
name: "test1"
port: 8080
arch: "clean"
router: "chi" # or gin / echo / fiber
router: "chi"
db: "postgres"

entities:
- user
- product
- payment
7 changes: 3 additions & 4 deletions templates/rest/clean/internal/handler/example_handler.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package handler

import (
"{{.ModuleName}}/internal/service"
"net/http"

"github.com/gin-gonic/gin"
{{.ImportHandler}}
)

type {{.Entity}}Handler struct {
Expand All @@ -15,7 +14,7 @@ func New{{.Entity}}Handler(s *service.{{.Entity}}Service) *{{.Entity}}Handler {
return &{{.Entity}}Handler{Service: s}
}

func (h *{{.Entity}}Handler) Get{{.Entity}}s(c *gin.Context) {
func (h *{{.Entity}}Handler) Get{{.Entity}}s({{.FullContext}}) {{.Returnable}}{
{{.LowerEntity}}s, _ := h.Service.Get{{.Entity}}s()
c.JSON(http.StatusOK, {{.LowerEntity}}s)
{{.ReturnKeyword}} {{.ToTheClient}} {{.LowerEntity}}s)
}
3 changes: 2 additions & 1 deletion templates/rest/clean/internal/server/routes.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ func (s *Server) RegisterRoutes() {{.HTTPHandler}} {

gormDB := s.db.GetDB()


{{- if .IsAPIGroup }}
api := r.Group("/api/v1")
{{- end }}

{{ if .Entities }}
{{ range $i, $entity := .Entities }}
Expand Down
Loading