# First Widgets AGS is the predecessor of Astal, which was written purely in TypeScript and so only supported JavaScript/TypeScript. Now it serves as a scaffolding tool for Astal projects in TypeScript. While what made AGS what it is, is now part of the Astal project, for simplicity we will refer to the Astal TypeScript lib as AGS. :::tip If you are not familiar with the JavaScript syntax [MDN](https://developer.mozilla.org/en-US/) and [javascript.info](https://javascript.info/) have great references. ::: ## Getting Started Start by initializing a project ```sh ags --init ``` then run `ags` in the terminal ```sh ags ``` Done! You have now a custom written bar using Gtk. :::tip AGS will transpile every `.ts`, `.jsx` and `.tsx` files into regular javascript then it will bundle everything into a single javascript file which then GJS can execute. The bundler used is [esbuild](https://esbuild.github.io/). ::: ## Root of every shell component: Window Astal apps are composed of widgets. A widget is a piece of UI that has its own logic and style. A widget can be as small as a button or an entire bar. The top level widget is always a [Window](https://aylur.github.io/libastal/class.Window.html) which will hold all widgets. ::: code-group ```tsx [widget/Bar.tsx] function Bar(monitor = 0) { return Content of the widget } ``` ::: ::: code-group ```ts [app.ts] import Bar from "./widget/Bar" App.start({ main() { Bar(0) Bar(1) // instantiate for each monitor }, }) ``` ::: ## Creating and nesting widgets Widgets are JavaScript functions which return Gtk widgets, either by using JSX or using a widget constructor. :::code-group ```tsx [MyButton.tsx] function MyButton(): JSX.Element { return } ``` ```ts [MyButton.ts] import { Widget } from "astal" function MyButton(): Widget.Button { return Widget.Button({ onClicked: "echo hello", label: "Click Me!", }) } ``` ::: :::info The only difference between the two is the return type. Using markup the return type is always `Gtk.Widget` (globally available as `JSX.Element`), while using constructors the return type is the type of the widget. It is rare to need the actual return type, so most if not all of the time, you can use markup. ::: Now that you have declared `MyButton`, you can nest it into another component. ```tsx function MyBar() { return Click The button } ``` Notice that widgets you defined start with a capital letter ``. Lowercase tags are builtin widgets, while capital letter is for custom widgets. ## Displaying Data JSX lets you put markup into JavaScript. Curly braces let you “escape back” into JavaScript so that you can embed some variable from your code and display it. ```tsx function MyWidget() { const label = "hello" return } ``` You can also pass JavaScript to markup attributes ```tsx function MyWidget() { const label = "hello" return