π¨π»βπ» Letβs walk through our Go project step-by-step. We're building a CLI note-taking tool
Handles:
- User input,
- Note creation,
- Displaying and saving the note.
Defines:
- The
Note
struct, - Methods for displaying and saving,
- A constructor function
New()
for creating validated notes.
package main
Declares this as the main package, the entry point of the program.
import (
"bufio"
"fmt"
"os"
"strings"
"example.com/go-project/note"
)
bufio
,os
: for reading input from terminal.strings
: to trim newline characters.fmt
: for printing output.note
: custom module for handling notes.
This function prints a prompt and reads the user's typed input.
reader := bufio.NewReader(os.Stdin)
text, err := reader.ReadString('\n')
- Uses
bufio.NewReader
for better line reading thanfmt.Scanln
. - Trims
\n
or\r
(cross-platform newline handling).
Prompts user for both title
and content
:
title := getUserInput("Note Title:")
content := getUserInput("Note Content:")
return title, content
This is the driver logic:
title, content := getNoteData()
userNote, err := note.New(title, content)
- Calls constructor from the
note
package. - Validates empty fields.
userNote.Display()
- Shows note title and content.
err = userNote.Save()
- Writes the note to a
.json
file.
package note
This is a custom package named note
.
type Note struct {
Title string `json:"title"`
Content string `json:"content"`
CreatedAt time.Time `json:"created_at"`
}
A custom type Note
with:
- Title (user-entered)
- Content (user-entered)
- CreatedAt (timestamp when note is created)
JSON tags make sure this struct is saved with the correct key names when encoded to JSON.
fmt.Printf("π Your note Titled %v has the following Content:\n\n%v\n", n.Title, n.Content)
- Method on
Note
- Displays nicely formatted note in terminal
fileName := strings.ReplaceAll(n.Title, " ", "_")
fileName = strings.ToLower(fileName) + ".json"
- Converts title like
My Note
tomy_note.json
json, err := json.Marshal(n)
- Marshals (converts)
Note
struct to JSON
return os.WriteFile(fileName, json, 0644)
- Saves it to a file with read-write permission
if title == "" || content == "" {
return Note{}, errors.New("invalid input")
}
- Validates that both fields are not empty.
return Note{
Title: title,
Content: content,
CreatedAt: time.Now(),
}, nil
- Returns a new note with current timestamp.
If the user enters:
Note Title: Grocery List
Note Content: Buy eggs, milk, and bread.
A file grocery_list.json
is created:
{
"title": "Grocery List",
"content": "Buy eggs, milk, and bread.",
"created_at": "2025-07-03T15:04:05Z"
}
User Input β Struct Creation β JSON File Write
- We get title & content via terminal
- Validate and construct
Note
struct - Marshal it to JSON
- Save to file