quick_start
View Sourcetitle: Quick Start Guide description: Create your first Raxol application date: 2025-04-27 author: Raxol Team section: guides tags: [quick start, guide, tutorial, application, components]
Quick Start Guide: Your First Raxol App
This guide walks you through creating a simple stateful counter application using Raxol.
Prerequisites
Before you start, ensure you have:
Elixir installed: Raxol requires Elixir. You can find installation instructions on the official Elixir website.
A new Mix project (optional): If you don't have a project, create one:
mix new my_raxol_app cd my_raxol_app
1. Add Raxol Dependency
First, add raxol to your project's dependencies. Open your mix.exs file and update the deps function:
def deps do
[
{:raxol, "~> 0.1.0"}
# Or {:raxol, github: "Hydepwns/raxol"} for the latest code
]
endThen, fetch the dependency:
mix deps.get
For more details, see the Development Setup.
2. Create Your Application Module
Create a new Elixir file, for example, lib/my_raxol_app/application.ex, and define your application module. This module will use Raxol.Core.Runtime.Application and implement the render/1 callback to define the user interface.
Raxol offers two primary ways to define your UI within the render/1 function:
Method 1: Using the HEEx Sigil (~H)
This approach uses a syntax similar to HTML and is often convenient for static structures or when integrating with HEEx templates.
# lib/my_raxol_app/application.ex
defmodule MyRaxolApp.Application do
use Raxol.Core.Runtime.Application
# The render/1 callback defines the UI.
# It receives assigns (data) and must return rendered content.
@impl true
def render(assigns) do
~H"""
<box border="single" padding="1">
<text color="cyan" bold="true">Hello from HEEx!</text>
</box>
"""
end
enduse Raxol.Core.Runtime.Application: Imports necessary functions and defines the behaviour for a Raxol application.@impl true def render(assigns): Implements the required callback to define the UI structure.~H""" ... """: The HEEx sigil defines the component-based UI using HTML-like tags.
Method 2: Using Raxol.View and Component Functions
This approach uses standard Elixir function calls for components, often providing more flexibility for programmatically building complex UIs. Many examples in the /examples directory use this method.
# lib/my_raxol_app/application_view.ex
defmodule MyRaxolApp.ApplicationView do
use Raxol.Core.Runtime.Application
use Raxol.View # Use Raxol.View for this approach
import Raxol.View.Elements # Optional: Import elements for cleaner calls
@impl true
def render(assigns) do
# Use the view macro and nested component functions
view do
box border: :single, padding: 1 do
text content: "Hello from Raxol.View!", color: :cyan, attributes: [:bold]
end
end
end
end
use Raxol.View: Required to enable theviewmacro and component function syntax.import Raxol.View.Elements: Allows calling components likeboxandtextdirectly, otherwise you might needRaxol.View.Elements.box(...).view do ... end: A macro block containing nested component function calls (e.g.,box(...),text(...)). Note that attributes are passed as keyword lists or maps.
Choose the method that best suits your needs or project style. Both achieve the same goal of defining the UI.
2.5 Adding State and Interactivity (init, update)
Static UIs are useful, but most terminal applications need to manage state and respond to user input. Raxol handles this using the init/1 and update/2 callbacks, inspired by the Elm Architecture.
1. Initialize State with init/1
The init/1 callback is called once when the application starts. It should return the initial state of your application.
2. Handle Messages with update/2
The update/2 callback is triggered when a message is sent to your application (e.g., from a button click or a subscription). It receives the message and the current state, and returns the new state. Optionally, it can also return a Command for executing background tasks (see examples/advanced/commands.exs).
3. Render State in render/1
The render/1 callback receives the current state (as assigns) and uses it to draw the UI.
Example: A Simple Counter
Let's modify our application to be a counter. We'll use the Raxol.View method here for illustration.
# lib/my_raxol_app/counter.ex
defmodule MyRaxolApp.Counter do
use Raxol.Core.Runtime.Application
use Raxol.View
import Raxol.View.Elements
# 1. Define the initial state
@impl true
def init(_context), do: %{count: 0}
# 2. Handle messages to update the state
@impl true
def update(model, message) do
case message do
:increment ->
%{model | count: model.count + 1}
_ ->
model # Return the unchanged model for other messages
end
end
# 3. Render the UI based on the current state
@impl true
def render(assigns) do
view do
box border: :single, padding: 1 do
# Display the current count from assigns (state)
text content: "Count: \#{assigns.count}"
# Add a button that sends the :increment message when clicked
button label: "Increment", on_click: :increment
end
end
end
endinit/1returns the initial state%{count: 0}.update/2handles the:incrementmessage by returning a new state map with the count increased.render/1now usesassigns.countto display the value and includes a<button>component.- The
buttonhas anon_click: :incrementattribute. When clicked, Raxol sends the:incrementmessage to theupdate/2function.
Subscriptions (subscribe/1)
For handling external events like timers or keyboard events not tied to specific components, you can implement the subscribe/1 callback. It returns subscriptions that send messages to update/2. See examples/basic/subscriptions.exs for details and the Async Operations Guide for a full explanation.
3. Start the Application
To run your application, you can start it directly in iex using the new Lifecycle module:
<iex> Raxol.Core.Runtime.Lifecycle.start_application(MyRaxolApp.Counter)
# {:ok, #PID<0.xxx.0>}For long-running applications, you'll typically add the Raxol.Core.Runtime.Application to your application's supervision tree (e.g., in lib/my_raxol_app/application.ex if you used mix new --sup):
defmodule MyRaxolApp.Application do
use Application
def start(_type, _args) do
children = [
# Other children...
{Raxol.Core.Runtime.Application, app: MyRaxolApp.Counter} # Use the module defined previously
]
opts = [strategy: :one_for_one, name: MyRaxolApp.Supervisor]
Supervisor.start_link(children, opts)
end
endMake sure MyRaxolApp.Application is listed in your mix.exs application/0 function.
Next Steps
Congratulations! You've built and run your first Raxol application.
- Explore the different built-in UI Components.
- Dive deeper into Asynchronous Operations (Subscriptions & Commands).
- Configure the application startup using Runtime Options.
- Check out the
/examplesdirectory in the Raxol repository for more advanced use cases.