Flet is a Python library that allows developers to build real-time web, desktop, and mobile apps using Python, while Flutter handles the UI internally. In this article, we will learn how to create Flutter-like applications using the Flet library with only Python.
To start building apps with Flet, install the library using the following command in your terminal:
pip install flet
Below is an example that shows how a Flet application starts and runs.
import flet as flt
def myapp(page: flt.Page):
pass
flt.app(target=myapp)
Output
A blank app window opens with a default theme and a loading animation, because no UI elements are added yet.

Explanation:
- import flet as flt imports the Flet library.
- myapp() is the main function where UI components will be added.
- page represents the app window or screen.
- flt.app(target=myapp) starts the Flet application using the given function.
Changing App Theme in Flet
Flet allows you to easily switch the app theme between Light and Dark mode. By default, Flet follows your device’s system theme. You can override this behavior by explicitly setting the theme in code.
import flet as flt
def myapp(page: flt.Page):
# Set theme mode (DARK or LIGHT)
page.theme_mode = flt.ThemeMode.DARK
# Set window size
page.window_height = 400
page.window_width = 500
# Set app title
page.title = "GeeksApp using Flet"
page.update()
flt.app(target=myapp)
Output

Explanation:
- page.theme_mode controls the app theme.
- ThemeMode.DARK forces dark mode (use ThemeMode.LIGHT for light mode).
- page.window_height and page.window_width define the app window size.
- page.update() applies all changes to the UI.
Adding Text to Your Flet App
Now let’s add some text elements to the app. In Flet, UI elements (called widgets) are added to the page using the page.add() method.
import flet as flt
def myapp(page: flt.Page):
page.theme_mode = flt.ThemeMode.LIGHT
page.window_height = 400
page.window_width = 500
text = flt.TextField(
label="Introductory Text",
value="This App is made using Flet"
)
page.add(text)
page.title = 'GeeksApp using Flet'
page.update()
flt.app(target=myapp)
Output

Explanation:
- TextField() creates an input box.
- label appears at the top of the text field.
- value is the default text shown inside the field.
- page.add(text) displays the TextField on the app screen.
Important note
- When you use page.add(), Flet automatically updates the UI.
- If all changes are done using add(), calling page.update() is optional.
- For changes not added via add() (like page.title), it’s safer to call page.update().
- Using both add() and update() together is allowed and causes no errors.
Changing TextField Border Style
By default, a TextField in Flet uses an outline border. You can easily customize its appearance by changing the border property to remove the border or display only an underline.
Removing the border
text = flt.TextField(
label="Introductory Text",
value="This App is made using Flet",
border = flt.InputBorder.NONE
)
Output

Using an underline border
text = flt.TextField(
label="Introductory Text",
value="This App is made using Flet",
border = flt.InputBorder.UNDERLINE
)
Output

Explanation:
- InputBorder.OUTLINE (default) shows a full border.
- InputBorder.NONE removes the border completely.
- InputBorder.UNDERLINE shows only a bottom line under the text field.
Adding Simple Text (Without Input)
If you only want to display text (not accept input), use the Text() widget
import flet as flt
def myapp(page: flt.Page):
page.theme_mode = flt.ThemeMode.LIGHT
page.window_height = 400
page.window_width = 500
page.add(
flt.Text(
"Hello Geeks",
size=40,
color=flt.Colors.GREEN,
bgcolor=flt.Colors.YELLOW_300,
weight=flt.FontWeight.BOLD,
)
)
page.title = "GeeksApp using Flet"
page.update()
flt.app(target=myapp)
Output

Explanation:
- size sets the font size.
- color sets the text color.
- bgcolor sets the background color of the text.
- Higher numbers in color shades (e.g., YELLOW_300) make the color appear deeper.
- weight=FontWeight.BOLD makes the text bold.
Calculator using Flet
In this section, we will build a simple yet functional calculator application using the Flet library. This example demonstrates how common UI components like buttons, text, rows, and columns can be combined to create an interactive Flutter-like app using only Python.
import flet
from flet import (
Column,
Container,
ElevatedButton,
Page,
Row,
Text,
Colors,
FilledButton,
)
class CalculatorApp(Container):
def __init__(self):
super().__init__()
self.reset()
self.result = Text(value="0", color=Colors.WHITE, size=22)
self.content = self.build()
def build(self):
return Container(
width=325,
bgcolor=Colors.BLUE_900,
border_radius=15,
padding=20,
content=Column(
controls=[
Row(controls=[self.result], alignment="end"),
Row(controls=[
ElevatedButton("AC", bgcolor=Colors.YELLOW_400, color=Colors.BLACK, data="AC", on_click=self.on_button_clicked),
ElevatedButton("+/-", bgcolor=Colors.YELLOW_400, color=Colors.BLACK, data="+/-", on_click=self.on_button_clicked),
ElevatedButton("%", bgcolor=Colors.GREEN_900, color=Colors.WHITE, data="%", on_click=self.on_button_clicked),
ElevatedButton("/", bgcolor=Colors.GREEN_900, color=Colors.WHITE, data="/", on_click=self.on_button_clicked),
]),
Row(controls=[
FilledButton("7", data="7", color=Colors.WHITE, on_click=self.on_button_clicked),
FilledButton("8", data="8", color=Colors.WHITE, on_click=self.on_button_clicked),
FilledButton("9", data="9", color=Colors.WHITE, on_click=self.on_button_clicked),
ElevatedButton("*", bgcolor=Colors.GREEN_900, color=Colors.WHITE, data="*", on_click=self.on_button_clicked),
]),
Row(controls=[
FilledButton("4", data="4", color=Colors.WHITE, on_click=self.on_button_clicked),
FilledButton("5", data="5", color=Colors.WHITE, on_click=self.on_button_clicked),
FilledButton("6", data="6", color=Colors.WHITE, on_click=self.on_button_clicked),
ElevatedButton("-", bgcolor=Colors.GREEN_900, color=Colors.WHITE, data="-", on_click=self.on_button_clicked),
]),
Row(controls=[
FilledButton("1", data="1", color=Colors.WHITE, on_click=self.on_button_clicked),
FilledButton("2", data="2", color=Colors.WHITE, on_click=self.on_button_clicked),
FilledButton("3", data="3", color=Colors.WHITE, on_click=self.on_button_clicked),
ElevatedButton("+", bgcolor=Colors.GREEN_900, color=Colors.WHITE, data="+", on_click=self.on_button_clicked),
]),
Row(controls=[
FilledButton("0", data="0", color=Colors.WHITE, on_click=self.on_button_clicked),
FilledButton("00", data="00", color=Colors.WHITE, on_click=self.on_button_clicked),
ElevatedButton(".", bgcolor=Colors.AMBER_600, color=Colors.WHITE, data=".", on_click=self.on_button_clicked),
ElevatedButton("=", bgcolor=Colors.ORANGE, color=Colors.WHITE, data="=", on_click=self.on_button_clicked),
]),
],
),
)
def on_button_clicked(self, e):
data = e.control.data
if self.result.value == "Error" or data == "AC":
self.result.value = "0"
self.reset()
elif data in ("0","1","2","3","4","5","6","7","8","9",".","00"):
if self.result.value == "0" or self.new_operand:
self.result.value = data
self.new_operand = False
else:
self.result.value += data
elif data in ("+","-","*","/"):
self.result.value = self.calculate(self.operand1, float(self.result.value), self.operator)
self.operator = data
self.operand1 = 0 if self.result.value == "Error" else float(self.result.value)
self.new_operand = True
elif data == "=":
self.result.value = self.calculate(self.operand1, float(self.result.value), self.operator)
self.reset()
elif data == "%":
self.result.value = str(float(self.result.value) / 100)
self.reset()
elif data == "+/-":
val = float(self.result.value)
self.result.value = str(-val if val > 0 else abs(val))
self.update()
def calculate(self, a, b, op):
if op == "+": return self.format(a + b)
if op == "-": return self.format(a - b)
if op == "*": return self.format(a * b)
if op == "/": return "Error" if b == 0 else self.format(a / b)
def format(self, num):
return str(int(num)) if num % 1 == 0 else str(num)
def reset(self):
self.operator = "+"
self.operand1 = 0
self.new_operand = True
def myCal(page: Page):
page.title = "Basic Calculator using Flet"
page.window_height = 375
page.window_width = 350
page.add(CalculatorApp())
flet.app(target=myCal)
Output

Explanation:
- Container creates the main calculator layout with background color, padding, and rounded corners.
- Column and Row organize the display and buttons like a real calculator.
- Text shows the current number or result on the screen.
- FilledButton is used for number buttons (0–9, 00) with light blue styling.
- ElevatedButton is used for operators and actions (+, -, *, /, =, AC).
- data identifies which button is pressed.
- on_button_clicked() handles input, operations, and resets.
- calculate() performs arithmetic operations.
- reset() clears values for the next calculation.