🚧 VeloxKit is pre-release software. APIs may change before v1.0. Get started →
Documentation
Guides
Custom Title Bar

Custom Title Bar

VeloxKit lets you replace the OS title bar with any React component. Set decorations: false in your config to get a frameless window, then build your own title bar in React.

Enable frameless window

In veloxkit.config.json:

{
  "window": {
    "decorations": false
  }
}

The OS title bar is removed. Your React component fills the entire window area.

Drag regions

Mark any View as a drag region with the veloxDraggable prop:

function TitleBar() {
  return (
    <View
      veloxDraggable
      style={{
        height: 44,
        flexDirection: 'row',
        alignItems: 'center',
        paddingHorizontal: 16,
        background: '#0E0E14',
      }}
    >
      <Text style={{ flex: 1, color: '#F0F0F2' }}>My App</Text>
 
      {/* Pressable children inside a drag region still receive press events */}
      <Pressable onPress={openMenu}>
        <Text style={{ color: '#A0A0B2' }}>Menu</Text>
      </Pressable>
    </View>
  )
}

veloxDraggable is a VeloxKit component prop, not a CSS style. Click-and-drag on a veloxDraggable view moves the window. Pressable children inside still fire their own onPress events normally.

Window controls

Use the built-in WindowControls component, or build your own:

import { WindowControls } from 'veloxkit'
 
function TitleBar() {
  return (
    <View veloxDraggable style={{ height: 44, flexDirection: 'row', alignItems: 'center' }}>
      <Text style={{ flex: 1, paddingLeft: 16, color: '#F0F0F2' }}>My App</Text>
      <WindowControls />
    </View>
  )
}

Or build custom controls with veloxWindow:

import { veloxWindow } from 'veloxkit'
 
function WindowControls() {
  return (
    <View style={{ flexDirection: 'row' }}>
      <Pressable
        onPress={() => veloxWindow.setMinimized()}
        style={({ hovered }) => ({
          width: 46, height: 32,
          alignItems: 'center', justifyContent: 'center',
          background: hovered ? '#2A2A3A' : 'transparent',
        })}
      >
        <Text style={{ color: '#A0A0B2', fontSize: 16 }}>─</Text>
      </Pressable>
 
      <Pressable
        onPress={() => veloxWindow.setMaximized(!veloxWindow.isMaximized())}
        style={({ hovered }) => ({
          width: 46, height: 32,
          alignItems: 'center', justifyContent: 'center',
          background: hovered ? '#2A2A3A' : 'transparent',
        })}
      >
        <Text style={{ color: '#A0A0B2', fontSize: 12 }}>□</Text>
      </Pressable>
 
      <Pressable
        onPress={() => veloxWindow.close()}
        style={({ hovered }) => ({
          width: 46, height: 32,
          alignItems: 'center', justifyContent: 'center',
          background: hovered ? '#C42B1C' : 'transparent',
        })}
      >
        <Text style={{ color: hovered ? '#fff' : '#A0A0B2' }}>✕</Text>
      </Pressable>
    </View>
  )
}

Platform detection

Use veloxWindow.platform() to adapt the title bar per OS:

import { veloxWindow } from 'veloxkit'
 
function TitleBar() {
  const isMac = veloxWindow.platform() === 'macos'
 
  return (
    <View
      veloxDraggable
      style={{
        height: 44,
        flexDirection: 'row',
        alignItems: 'center',
        // macOS: leave room on the left for the native traffic light buttons
        paddingLeft: isMac ? 76 : 16,
        paddingRight: 12,
        background: '#0E0E14',
      }}
    >
      <View style={{ flex: 1 }}>
        <TextInput placeholder="Search..." style={{ maxWidth: 280 }} />
      </View>
 
      {/* Only render custom controls on Windows/Linux */}
      {!isMac && <WindowControls />}
    </View>
  )
}

On macOS with decorations: false, the native traffic light buttons (close / minimize / maximize) remain visible in the top-left corner. You do not need to render your own close button on macOS.

Edge resize

VeloxKit automatically provides 8px edge resize zones on frameless windows. No additional code is needed.

Full example

import { View, Text, Pressable, TextInput } from 'veloxkit'
import { veloxWindow, WindowControls } from 'veloxkit'
 
export function AppShell({ children }) {
  const isMac = veloxWindow.platform() === 'macos'
 
  return (
    <View style={{ flex: 1, flexDirection: 'column' }}>
      <View
        veloxDraggable
        style={{
          height: 44,
          flexDirection: 'row',
          alignItems: 'center',
          paddingLeft: isMac ? 76 : 16,
          paddingRight: 12,
          background: '#0E0E14',
          borderBottomWidth: 1,
          borderBottomColor: '#2A2A3A',
        }}
      >
        <Text style={{ color: '#F0F0F2', fontWeight: 600, flex: 1 }}>My App</Text>
        {!isMac && <WindowControls />}
      </View>
 
      <View style={{ flex: 1 }}>
        {children}
      </View>
    </View>
  )
}