Library / SDK
spyoungtech/FreeSimpleGUI avatar
spyoungtech/FreeSimpleGUI

FreeSimpleGUI: a maintained LGPL fork of PySimpleGUI with the same layout and element API

The free-forever GUI library

866 stars106 forksPythonLGPL-3.0

At a glance

What is it?
FreeSimpleGUI is a fork of PySimpleGUI that keeps the layout and element API intact while dropping the commercial licensing of the original, so existing scripts need only an import change. It also ships separate backends for Qt, WxPython and Remi alongside tkinter, and a set of console entry points for issuing bug reports.
Who is it for?
FreeSimpleGUI fits a Python developer with existing PySimpleGUI code who needs a licence that does not require a commercial key for internal tools, course examples or hobby projects, and who is content to stay inside the tkinter, Qt, WxPython and Remi backends the library exposes. It does not fit a team that needs the newest upstream features as they land or a library whose widgets are documented in depth beyond the fork's own docs.
Can I use it commercially?
Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The migration is one import line

FreeSimpleGUI's pitch is continuity with PySimpleGUI, and the documentation is unusually direct about it. The project describes itself as the free-forever Python Simple GUI software, and the migration instruction is a diff, which is the clearest possible statement of what changes:

diff
- import PySimpleGUI as sg
+ import FreeSimpleGUI as sg

Nothing else in the guide is presented as different. The layout structure, the element names, the window object and the read loop are all described as they were, so a script that runs against PySimpleGUI is expected to run against this fork after the import statement is edited and the package name is changed in the pip command.

That is a genuinely rare situation in a fork. Most forks diverge: a method is renamed, a default changes, a deprecation warning appears. The reason this one can stay close is the licensing change, and the LGPL-3.0 licence field on the repository is the point of the exercise rather than an afterthought. The pyproject.toml describes the project as the free-forever Python GUI framework, with the author and maintainer listed as Spencer Phillip Young, and the keywords include PySimpleGui and fork alongside the framework names.

The repository layout backs up the multi-backend claim. Alongside the main FreeSimpleGUI package there are separate FreeSimpleGUIQt, FreeSimpleGUIWx and FreeSimpleGUIWeb directories, plus psgtray.py at the top level for the system tray piece carried over from the original project.

Install and run the five-part program structure

Installation is a single pip command:

bash
pip install FreeSimpleGUI

The documentation then walks through what it calls the anatomy of a simple program, broken into five sections: the import, the layout, the window definition, the event loop or window.read call, and closing the window. The complete one-shot example is:

python
import FreeSimpleGUI as sg                        # Part 1 - The import

# Define the window's contents
layout = [  [sg.Text("What's your name?")],     # Part 2 - The Layout
            [sg.Input()],
            [sg.Button('Ok')] ]

# Create the window
window = sg.Window('Window Title', layout)      # Part 3 - Window Defintion

# Display and interact with the Window
event, values = window.read()                   # Part 4 - Event loop or Window.read call

# Do something with the information gathered
print('Hello', values[0], "! Thanks for trying FreeSimpleGUI")

# Finish up by removing from the screen
window.close()                                  # Part 5 - Close the Window

Two details in that snippet are worth pausing on. The layout is a list of lists, and each inner list is a row, so the structure of the widget arrangement is literal rather than a separate object model. And the read call returns two things, the event and a values dictionary, so even the simplest program returns a mapping rather than a single result.

For a package whose whole argument is brevity, the documentation quantifies the claim: depending on the program and framework used, a FreeSimpleGUI program may require between one half and one tenth of the code to create an identical window using one of the frameworks directly. That is a rough range rather than a measurement, and no benchmark is offered.

Four backends behind one layout, and escape hatches when they are not enough

The library targets tkinter, Qt, WxPython and Remi, and the documentation is careful about what that abstraction does and does not promise. The stated goal is to encapsulate and hide the specific objects and code of the underlying framework, so your program does not have to know which toolkit it is running on. But the same section says that if a setting or feature is not yet exposed through the FreeSimpleGUI APIs, you are not walled off from the framework: you can reach the underlying widgets and windows directly and expand capabilities without modifying the package itself.

That is the design decision that decides whether this library is a good fit for you. A wrapper that hides everything is pleasant until the one thing you need is missing. A wrapper that hides most things but lets you drop down at any point turns that frustration into a small amount of framework-specific code in one function. Remi is the interesting backend in that list, since it is the browser-based option, and a browser-backed window has different assumptions about layout than a native toolkit.

The GUI elements are called Elements in this library, and the element vocabulary includes the standard widgets plus progress bars and progress meters, which the keywords list names explicitly. That vocabulary is one of the practical reasons to stay on the fork rather than reach past it: if you write the widget set in the fork's terms, the same code can move to another supported backend later.

Keys, the values dictionary and updating an element in place

The interactive example differs from the one-shot in three specific ways, and they are the mechanics you need for anything beyond a single prompt. First, elements can be given a key, which the documentation describes as a name for an element, or in Python terms a dictionary key. Second, an element can be given a size in characters, so a Text element declared as size=(40,1) is forty characters wide and one character high. Third, a blank Text element can be updated later by looking it up through its key.

The updated element in the example is declared with a size and a key and no text string, which is what makes it blank:

python
          [sg.Text(size=(40,1), key='-OUTPUT-')],

And the update statement, which is the line that makes the window interactive:

python
    window['-OUTPUT-'].update('Hello ' + values['-INPUT-'] + "! Thanks for trying FreeSimpleGUI")

The exit condition in the event loop shows the two ways a program ends, and it uses the library's own constant for the window being closed:

python
    if event == sg.WINDOW_CLOSED or event == 'Quit':
        break

That last detail is a small but useful quality signal. Comparing the event to sg.WINDOW_CLOSED rather than to None means the loop does not have to know how the backend reports a closed window, which is exactly the kind of thing a wrapper that supports four toolkits should absorb on your behalf.

Console entry points for filing issues from inside the app

The pyproject.toml registers four console scripts, which is an unusual amount of tooling for a GUI library and worth knowing about before you design a support path for an application built on it:

code
fsgissue = "FreeSimpleGUI:main_open_github_issue"
fsgmain = "FreeSimpleGUI:_main_entry_point"
fsghelp = "FreeSimpleGUI:main_sdk_help"
fsgver = "FreeSimpleGUI:main_get_debug_data"

The names describe their purpose. fsgissue opens a GitHub issue, which is the path the documentation points users to when they hit a problem. fsgver produces debug data, which is the sort of output you paste into a bug report. fsghelp offers SDK help. fsgmain is a general entry point, and there is also an fsgsettings script that is truncated in the listing, pointing at a function whose name ends in a reference to the original PySimpleGUI settings.

This tells you something about the project's priorities. A GUI library that ships a bug-report command is optimising for the case where a user hits a problem in a small script and cannot easily reproduce it in a clean environment, and it is also why the documentation encourages opening an issue before sending a pull request, asking contributors to associate a change with an open issue where possible.

The version data matters for the same reason. fsgver exists so a user can report which build they are running, and the current version in pyproject.toml is 5.3.0.post1, with the tag v5.3.0.post1 released on 2026-08-27 and v5.3.0 on 2026-08-21. The previous release listed is v5.2.0.post1 from 2025-03-17.

Where a fork like this is the wrong choice

The honest reason to look elsewhere is upstream divergence. A fork exists because of a disagreement, and disagreements get resolved in one direction or the other. If the original PySimpleGUI project changes its API in a way the fork does not follow, or stops shipping the backend you rely on, you are reading documentation for a library that no longer has a matching upstream. The fork does mitigate this by carrying its own documentation at freesimplegui.readthedocs.io and by noting that FreeSimpleGUI.org is still in progress, which tells you the documentation story itself is not finished.

There is also a question about what you lose when you drop below the wrapper. The library is explicit that you can reach the underlying framework's widgets directly when the API does not expose something, which is a fair escape hatch, but it means the code you write against the raw widgets is code tied to a specific toolkit and a specific fork version. The abstraction holds for the elements the library implements and thins out immediately after that.

For a production desktop application with a designer, a web frontend or a native mobile target, this is the wrong category of tool, because the value of the wrapper comes from writing the interface as code in a handful of lines and a large product has neither the line budget nor the widget vocabulary. For an internal script, a teaching example, a quick tool for a colleague, or a course, the same constraint is the entire benefit.

The licensing point deserves its own note rather than being folded in. The library is LGPL-3.0, which for a Python library distributed as source has different obligations than the commercial key the original project introduced, and the repository ships a license.txt file alongside a NOTICE file. Read the actual file rather than relying on a summary, because how you ship a modified library inside a larger application is the question that matters.

Editorial conclusion

FreeSimpleGUI fits a Python developer with existing PySimpleGUI code who needs a licence that does not require a commercial key for internal tools, course examples or hobby projects, and who is content to stay inside the tkinter, Qt, WxPython and Remi backends the library exposes. It does not fit a team that needs the newest upstream features as they land or a library whose widgets are documented in depth beyond the fork's own docs. Before adopting it, check the version you pin, which is currently 5.3.0.post1, confirm that the elements and layout features your existing scripts use are present in the fork's own documentation rather than only upstream, and read license.txt yourself, since the licence is LGPL-3.0 and the fork's obligations differ from the original project's.

Frequently asked questions

How do I migrate from PySimpleGUI to FreeSimpleGUI?

The documentation gives the migration as a one-line import change, from import PySimpleGUI as sg to import FreeSimpleGUI as sg. The package is installed with `pip install FreeSimpleGUI` and the layout, element and window APIs are described as unchanged.

Which GUI frameworks does FreeSimpleGUI support?

It supports tkinter, Qt, WxPython and Remi, and the repository contains separate FreeSimpleGUIQt, FreeSimpleGUIWx and FreeSimpleGUIWeb packages alongside the main one. The documentation says you can still access the underlying framework's widgets directly when a feature is not exposed through the FreeSimpleGUI API.

What licence does FreeSimpleGUI use and what version is current?

The licence is LGPL-3.0, with a license.txt file in the repository. The current version in pyproject.toml is 5.3.0.post1, and the tags v5.3.0.post1 and v5.3.0 were published in August 2026.

How do you update a widget in a FreeSimpleGUI window?

Give the element a key, such as the Text element declared with size=(40,1) and key='-OUTPUT-', then update it with window['-OUTPUT-'].update(...). The values dictionary returned by window.read() uses those same keys for the input values.

Does FreeSimpleGUI provide tools for reporting bugs?

The package registers console scripts including fsgissue, which opens a GitHub issue, and fsgver, which produces debug data for a report, along with fsghelp and fsgsettings. The documentation asks contributors to associate a pull request with an open issue where possible.

Official sources

  1. Issues
  2. License: LGPL-3.0
  3. README
  4. Releases
  5. spyoungtech/FreeSimpleGUI on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/spyoungtech-freesimplegui.svg)](https://hysenlabs.com/projects/spyoungtech-freesimplegui)

Was this useful?