> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sirius.menu/llms.txt
> Use this file to discover all available pages before exploring further.

# Windows

> How to create and manage windows, tabs, and sections in Rayfield.

<Note>
  **Share your script with the community.**

  Publish your script on [RoScripts](https://roscripts.io) so players can find your script.
</Note>

## Create a window

`Rayfield:CreateWindow()` is the entry point for your UI. Call it once after loading the library.

```lua theme={null}
local Window = Rayfield:CreateWindow({
   Name = "Rayfield Example Window",
   Icon = 0, -- Icon in Topbar. Can use Lucide Icons (string) or Roblox Image (number). 0 to use no icon (default).
   LoadingTitle = "Rayfield Interface Suite",
   LoadingSubtitle = "by Sirius",
   ShowText = "Rayfield", -- for mobile users to unhide Rayfield, change if you'd like
   Theme = "Default", -- Check https://docs.sirius.menu/rayfield/configuration/themes

   ToggleUIKeybind = "K", -- The keybind to toggle the UI visibility (string like "K" or Enum.KeyCode)

   DisableRayfieldPrompts = false,
   DisableBuildWarnings = false, -- Prevents Rayfield from emitting warnings when the script has a version mismatch with the interface.

   -- ScriptID = "sid_xxxxxxxxxxxx", -- Your Script ID from developer.sirius.menu — enables analytics, managed keys, and script hosting

   ConfigurationSaving = {
      Enabled = true,
      FolderName = nil, -- Create a custom folder for your hub/game
      FileName = "Big Hub"
   },

   Discord = {
      Enabled = false, -- Prompt the user to join your Discord server if their executor supports it
      Invite = "noinvitelink", -- The Discord invite code, do not include Discord.gg/. E.g. Discord.gg/ABCD would be ABCD
      RememberJoins = true -- Set this to false to make them join the Discord every time they load it up
   },

   KeySystem = false, -- Set this to true to use our key system
   KeySettings = {
      Title = "Untitled",
      Subtitle = "Key System",
      Note = "No method of obtaining the key is provided", -- Use this to tell the user how to get a key
      FileName = "Key", -- It is recommended to use something unique, as other scripts using Rayfield may overwrite your key file
      SaveKey = true, -- The user's key will be saved, but if you change the key, they will be unable to use your script
      GrabKeyFromSite = false, -- If this is true, set Key below to the RAW site you would like Rayfield to get the key from
      Key = {"Hello"} -- List of keys that the system will accept, can be RAW file links (pastebin, github, etc.) or simple strings ("hello", "key22")
   }
})
```

### Options

<ResponseField name="Name" type="string" required>
  The title displayed in the window header.
</ResponseField>

<ResponseField name="Icon" type="number | string">
  Icon shown in the topbar. Pass a Roblox image ID (number), a Lucide icon name (string), or `0` for no icon.
</ResponseField>

<ResponseField name="LoadingTitle" type="string">
  Title shown on the loading screen.
</ResponseField>

<ResponseField name="LoadingSubtitle" type="string">
  Subtitle shown on the loading screen.
</ResponseField>

<ResponseField name="ShowText" type="string">
  Text shown to mobile users to unhide the UI.
</ResponseField>

<ResponseField name="Theme" type="string | table">
  The theme to apply. Pass a theme identifier string or a custom theme table. See [Themes](/rayfield/themes).
</ResponseField>

<ResponseField name="ToggleUIKeybind" type="string | Enum.KeyCode">
  The key that toggles UI visibility.
</ResponseField>

<ResponseField name="DisableRayfieldPrompts" type="boolean">
  Suppresses built-in Rayfield prompts.
</ResponseField>

<ResponseField name="DisableBuildWarnings" type="boolean">
  Prevents Rayfield from emitting warnings when there is a version mismatch between your script and the interface.
</ResponseField>

<ResponseField name="ScriptID" type="string">
  Your Script ID from the [Sirius Developer Platform](https://developer.sirius.menu). Connects your script to the platform for analytics, managed keys, and hosted script delivery. Create a project at [developer.sirius.menu](https://developer.sirius.menu) to get your Script ID.
</ResponseField>

<ResponseField name="ConfigurationSaving" type="object">
  Controls automatic configuration saving.

  <Expandable title="ConfigurationSaving options">
    <ResponseField name="Enabled" type="boolean">
      Enables configuration saving.
    </ResponseField>

    <ResponseField name="FolderName" type="string | nil">
      Custom folder name for saved config files. Leave `nil` to use the default.
    </ResponseField>

    <ResponseField name="FileName" type="string">
      The name of the saved config file.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="Discord" type="object">
  Prompts the user to join your Discord server on supported executors.

  <Expandable title="Discord options">
    <ResponseField name="Enabled" type="boolean">
      Enables the Discord join prompt.
    </ResponseField>

    <ResponseField name="Invite" type="string">
      Your Discord invite code, without `discord.gg/`. For example, `discord.gg/ABCD` → `"ABCD"`.
    </ResponseField>

    <ResponseField name="RememberJoins" type="boolean">
      When `true`, the user is only prompted once. When `false`, they are prompted every load.
    </ResponseField>
  </Expandable>
</ResponseField>

<Warning>
  The key system UI loads a detectable Roblox model. [Secure Mode](/rayfield/secure-mode) blocks the key UI entirely. Users without a saved key from a previous session won't be able to load the script.
</Warning>

<ResponseField name="KeySystem" type="boolean">
  Enables the key system. Configure it with `KeySettings`.
</ResponseField>

<ResponseField name="KeySettings" type="object">
  Settings for the key system. Only used when `KeySystem` is `true`.

  <Expandable title="KeySettings options">
    <ResponseField name="Title" type="string">
      Title displayed on the key prompt.
    </ResponseField>

    <ResponseField name="Subtitle" type="string">
      Subtitle displayed on the key prompt.
    </ResponseField>

    <ResponseField name="Note" type="string">
      Instructions for obtaining the key, shown to the user.
    </ResponseField>

    <ResponseField name="FileName" type="string">
      File name used to save the key locally. Use something unique to avoid conflicts with other Rayfield scripts.
    </ResponseField>

    <ResponseField name="SaveKey" type="boolean">
      When `true`, the user's key is saved so they don't need to re-enter it. Note: changing the key will invalidate saved keys.
    </ResponseField>

    <ResponseField name="GrabKeyFromSite" type="boolean">
      When `true`, Rayfield fetches the key from the URL specified in `Key`.
    </ResponseField>

    <ResponseField name="Key" type="table">
      A list of accepted keys (strings), or RAW file URLs (Pastebin, GitHub, etc.) when `GrabKeyFromSite` is `true`.
    </ResponseField>
  </Expandable>
</ResponseField>

<Tip>
  Looking for server-validated keys with ad-gated delivery? The [Sirius Developer Platform](https://developer.sirius.menu) offers a managed key system with user-hash locking, per-key watermarks, and ad provider integration — available on all plans including Free.
</Tip>

***

## Create a tab

Tabs are the top-level sections inside a window. Each tab can hold its own elements.

```lua theme={null}
local Tab = Window:CreateTab("Tab Example", 4483362458) -- Title, Image
```

### Lucide icon support

You can use a [Lucide icon](https://lucide.dev/icons/) name in place of a Roblox image ID.

```lua theme={null}
local Tab = Window:CreateTab("Tab Example", "rewind")
```

<Note>
  Not all Lucide icons are supported. See the [full list of supported icons](https://github.com/latte-soft/lucide-roblox/tree/master/icons/compiled/48px). Credit to [Lucide](https://lucide.dev/) and [Latte Softworks](https://github.com/latte-soft/).
</Note>

<Warning>
  Lucide icons and Roblox image IDs are detectable by game anti-cheats. If you need your script to be undetectable, use `getcustomasset()` instead. See [Secure Mode](/rayfield/secure-mode) for details.
</Warning>

***

## Create a section

Sections add a labelled group header inside a tab.

```lua theme={null}
local Section = Tab:CreateSection("Section Example")
```

### Update a section

```lua theme={null}
Section:Set("Section Example")
```

***

## Create a divider

Dividers add a horizontal rule inside a tab to visually separate content.

```lua theme={null}
local Divider = Tab:CreateDivider()
```

### Update a divider

```lua theme={null}
Divider:Set(false) -- Whether the divider's visibility is to be set to true or false.
```

***

## Visibility

### Set visibility

```lua theme={null}
Rayfield:SetVisibility(false)
```

### Get visibility

```lua theme={null}
Rayfield:IsVisible()
```

***

## Destroy the interface

```lua theme={null}
Rayfield:Destroy()
```
