Skip to content
Subha Sundar Das edited this page Jul 14, 2026 · 6 revisions

New to RetUI? You're in the right place.

There are only 8 ideas to learn. Once they click, everything else in RetUI will make sense. Let's go through them one at a time, with real, working code.


1. Everything is a Component

Think of a component as a little Lego brick. You snap bricks together to build bigger things.

In code, a component is just a Go function that returns a retui.Element. That's it.

func Greeting() retui.Element {
    return retui.Text("Hello, World!", retui.NewStyle())
}

Want to use it? Just call it:

func App() retui.Element {
    return Greeting()
}

πŸ‘‰ Takeaway: if a function returns retui.Element, it's a component. You'll write dozens of these.


2. Components Nest Inside Each Other

Here's the part that makes RetUI powerful: components can contain other components.

The main container you'll use is Box. Think of Box as an invisible wrapper that arranges whatever you put inside it.

func App() retui.Element {
    return retui.Box(
        retui.Props{Direction: retui.Column},
        retui.NewStyle(),
        retui.Text("Welcome", retui.NewStyle().Bold(true)),
        retui.Text("Hello RetUI!", retui.NewStyle()),
    )
}

That's a Box holding two pieces of text, stacked vertically:

Welcome
Hello RetUI!

You can keep nesting boxes inside boxes, as deep as you need:

Box
β”œβ”€β”€ Box
β”‚   β”œβ”€β”€ Text
β”‚   └── Text
└── Text

πŸ‘‰ Takeaway: Box is your building container. Everything lives inside one.


3. Don't Worry About Redrawing β€” RetUI Does It For You

Here's something nice: you never manually clear or redraw the screen.

When your app's data changes, RetUI notices and updates only the part of the screen that changed.

Before:  Counter: 5
After:   Counter: 6

Only the 6 gets touched. Nothing else flickers or reprints. This is what keeps terminal apps feeling instant.

πŸ‘‰ Takeaway: change your data, RetUI handles the screen.


4. State = Data That Can Change

"State" is just a fancy word for a value your component remembers and can update.

Without state, text is stuck forever:

retui.Text("Counter: 0", retui.NewStyle())

With state, it can change over time:

count, setCount := retui.UseState(0)

retui.Text(fmt.Sprintf("Counter: %d", count), retui.NewStyle())

  • count β†’ the current value
  • setCount β†’ the function you call to change it
setCount(count + 1) // bumps the counter, screen updates automatically

Try it: a real, working counter

import (
    "fmt"
"github.com/subhasundardass/retui/retui"
"github.com/subhasundardass/retui/retui/components"

)

func Counter() retui.Element { count, setCount := retui.UseState(0)

return retui.Box(
    retui.Props{Direction: retui.Column, Gap: 1},
    retui.NewStyle(),
    retui.Text(fmt.Sprintf("Counter: %d", count), retui.NewStyle()),
    components.Button().
        ID("increment").
        Label("Increment").
        OnClick(func(id string) {
            setCount(count + 1)
        }).
        Render(),
)

}

Copy this into your app and run it β€” press the button, watch the number climb. That's state in action.

πŸ‘‰ Takeaway: UseState gives you a value + a way to change it. RetUI handles the rest.


5. Hooks: How Components Remember Things

"Hooks" sound intimidating, but they're just special functions that let a component hold onto information between renders.

You just met one β€” UseState. Here are all four:

Hook What it's for Beginner analogy
UseState Store a value that can change A sticky note your component keeps updating
UseStateKeyed Same, but for lists/trees where items can appear or disappear A sticky note labeled with a name instead of a position
UseEffect Run code when something changes (with optional cleanup) "When X happens, do Y"
UseContext Share a value with components deep inside, without passing it manually A shared bulletin board everyone can read

That's genuinely everything you need to start. Every other RetUI feature you'll learn later is just a variation on these same 8 ideas.

Core Concepts

New to RetUI? You're in the right place.

There are only 8 ideas to learn. Once they click, everything else in RetUI will make sense. Let's go through them one at a time, with real, working code.


1. Everything is a Component

Think of a component as a little Lego brick. You snap bricks together to build bigger things.

In code, a component is just a Go function that returns a retui.Element. That's it.

func Greeting() retui.Element {
    return retui.Text("Hello, World!", retui.NewStyle())
}

Want to use it? Just call it:

func App() retui.Element {
    return Greeting()
}

πŸ‘‰ Takeaway: if a function returns retui.Element, it's a component. You'll write dozens of these.


2. Components Nest Inside Each Other

Here's the part that makes RetUI powerful: components can contain other components.

The main container you'll use is Box. Think of Box as an invisible wrapper that arranges whatever you put inside it.

func App() retui.Element {
    return retui.Box(
        retui.Props{Direction: retui.Column},
        retui.NewStyle(),
        retui.Text("Welcome", retui.NewStyle().Bold(true)),
        retui.Text("Hello RetUI!", retui.NewStyle()),
    )
}

That's a Box holding two pieces of text, stacked vertically:

Welcome
Hello RetUI!

You can keep nesting boxes inside boxes, as deep as you need:

Box
β”œβ”€β”€ Box
β”‚   β”œβ”€β”€ Text
β”‚   └── Text
└── Text

πŸ‘‰ Takeaway: Box is your building container. Everything lives inside one.


3. Don't Worry About Redrawing β€” RetUI Does It For You

Here's something nice: you never manually clear or redraw the screen.

When your app's data changes, RetUI notices and updates only the part of the screen that changed.

Before:  Counter: 5
After:   Counter: 6

Only the 6 gets touched. Nothing else flickers or reprints. This is what keeps terminal apps feeling instant.

πŸ‘‰ Takeaway: change your data, RetUI handles the screen.


4. State = Data That Can Change

"State" is just a fancy word for a value your component remembers and can update.

Without state, text is stuck forever:

retui.Text("Counter: 0", retui.NewStyle())

With state, it can change over time:

count, setCount := retui.UseState(0)

retui.Text(fmt.Sprintf("Counter: %d", count), retui.NewStyle())

  • count β†’ the current value
  • setCount β†’ the function you call to change it
setCount(count + 1) // bumps the counter, screen updates automatically

Try it: a real, working counter

import (
    "fmt"
"github.com/subhasundardass/retui/retui"
"github.com/subhasundardass/retui/retui/components"

)

func Counter() retui.Element { count, setCount := retui.UseState(0)

return retui.Box(
    retui.Props{Direction: retui.Column, Gap: 1},
    retui.NewStyle(),
    retui.Text(fmt.Sprintf("Counter: %d", count), retui.NewStyle()),
    components.Button().
        ID("increment").
        Label("Increment").
        OnClick(func(id string) {
            setCount(count + 1)
        }).
        Render(),
)

}

Copy this into your app and run it β€” press the button, watch the number climb. That's state in action.

πŸ‘‰ Takeaway: UseState gives you a value + a way to change it. RetUI handles the rest.


5. Hooks: How Components Remember Things

"Hooks" sound intimidating, but they're just special functions that let a component hold onto information between renders.

You just met one β€” UseState. Here are all four:

Hook What it's for Beginner analogy
UseState Store a value that can change A sticky note your component keeps updating
UseStateKeyed Same, but for lists/trees where items can appear or disappear A sticky note labeled with a name instead of a position
UseEffect Run code when something changes (with optional cleanup) "When X happens, do Y"
UseContext Share a value with components deep inside, without passing it manually A shared bulletin board everyone can read

That's genuinely everything you need to start. Every other RetUI feature you'll learn later is just a variation on these same 8 ideas.

Clone this wiki locally