We’ve covered the ground: variables, loops, errors, concurrency, and rules. If you've actually followed along, your brain is probably buzzing, or at least a little bit tired. That's fine. Now, let’s stop looking at individual puzzle pieces and build a real, working thing. We’re going to build a CLI note manager. It’s not going to change the world, but it will survive a power cycle, which is more than I can say for some of my earlier experiments.
The roadmap
We’ll keep this simple:
notes/: Our home base.
storage.skink: Handling the JSON serialization and file I/O.
main.skink: Parsing your commands and making things happen.
The storage engine
We’ll store our notes in a file called notes.json. It’s simple, readable, and—most importantly—doesn't require a database server that takes up half your RAM.
// storage.skink
module storage
import "std/json"
import "std/fs"
pub struct Note {
title: string
body: string
}
pub fn loadNotes() -> ([]Note, bool) {
if !fs.Exists("notes.json") {
var empty []Note
return empty, true
}
text, err := fs.ReadAll("notes.json")
if err.message != "" {
var empty []Note
return empty, false
}
// Here is where you'd parse that JSON blob.
// I'll leave the Unmarshal heavy lifting as a challenge for you.
var empty []Note
return empty, true
}
The main entry point
The main function needs to act as the traffic controller. It checks what you're asking for, hits the storage engine, and reports back.
// main.skink
module main
import "std/str"
import "storage"
fn main(args: []string) -> int {
if len(args) < 2 {
print("usage: notes <list|add>")
return 1
}
cmd := args[1]
if str.Equal(cmd, "list") {
notes, ok := storage.loadNotes()
if !ok {
print("failed to load notes—have you broken the JSON again?")
return 1
}
for n in notes {
print("{n.title}: {n.body}")
}
} else if str.Equal(cmd, "add") {
print("Add is coming soon. I'm busy fixing the server.")
} else {
print("unknown command: {cmd}. Try 'list'.")
return 1
}
return 0
}
Building it
To compile this, point the compiler at all the files involved. It’ll stitch them together into your shiny new executable.
SKINK_HOME=/path/to/skink-lang skink -o notes main.skink storage.skink ./notes list
The "Real World" Homework
This is where you stop being a tourist and start being a developer:
- Finish the saveNotes function: Use json.MarshalValue and fs.WriteAll to actually persist those notes to the disk.
- Implement add: Extend main to accept arguments like add "title" "body".
- Add delete: Because we all have drafts we'd rather forget.
- Test it: Write a storage_test.skink to ensure your save and load logic actually works before you start trusting it with your grocery list.
Congratulations
You've made it. You've walked through the basics, seen the potential traps, and hopefully avoided the worst of the "midnight debugging" sessions. Skink is a powerful tool, and now it's yours to wield.
Go out there and build something useful.
Happy coding.
If you want tto carry, on, the next tutorial is Building a web server.