PureBasic
PureBasic is a commercial, high-level programming language derived from BASIC, designed for creating portable applications with simple syntax and fast native executables across multiple platforms including Windows, Linux, macOS, and Raspberry Pi.[1]
Developed by Fantaisie Software and primarily coded by founder Frédéric Laboureur, PureBasic emphasizes ease of use for both beginners and experienced programmers while supporting advanced features such as pointers, structures, procedures, inline assembly, full Unicode handling, strong typing, and namespaces.[2][1] The language includes over 1,600 built-in commands and libraries for tasks like 2D graphics via DirectX and OpenGL, 3D rendering with OGRE, and system-level programming without requiring external DLLs, resulting in compact 32-bit or 64-bit executables.[1]
Its history began with the first public release of version 2.00 on October 22, 2000, and has evolved through major updates, with the latest stable release being version 6.21 in June 2025 following the 6.20 LTS in February 2025; a beta for version 6.30 was released in September 2025.[3][4] PureBasic ships with an integrated development environment (IDE) featuring a debugger, profiler, form designer, and syntax highlighting, making it suitable for rapid application development in areas such as games, utilities, and desktop software.[1]
History and Development
Origins and Early Development
PureBasic's development began in mid-1998 under the leadership of Frédéric Laboureur, who founded Fantaisie Software to create a modern dialect of the BASIC programming language. The first version was released for AmigaOS that year. Motivated by the performance and size limitations of earlier BASIC interpreters and compilers such as QBASIC and Visual Basic, Laboureur aimed to deliver a tool that emphasized execution speed, syntactic simplicity, and native code compilation without requiring runtime libraries.[5][6][7][8] Subsequent efforts expanded to the Windows platform, leveraging DirectX and Win32 APIs to enable efficient multimedia and application development.[3]
The project's first public preview for Windows, version 2.00 PR1, was released on October 22, 2000, introducing core syntax elements along with foundational libraries for sprites, joysticks, and networking to support game and interactive programming.[3] Subsequent pre-release updates followed rapidly: PR2 and PR3 in November 2000 added support for requester gadgets, toolbar integration, and a dedicated code editor with syntax highlighting, addressing early usability concerns.[3] These iterations built on Laboureur's expertise in C and assembly, ensuring the compiler produced compact, standalone executables optimized for x86 architecture.[9]
The first stable release, version 2.00, arrived on December 17, 2000, incorporating a comprehensive 2D drawing library and refinements to DirectX integration, along with numerous bug fixes to solidify reliability.[3] From its inception, PureBasic adopted a commercial model centered on lifetime licenses, allowing users perpetual access to updates without recurring fees, which helped establish a dedicated user base early on.[7][10] This foundational phase laid the groundwork for later cross-platform expansions, though the core emphasis remained on Windows-centric performance.[3]
Major Releases and Milestones
PureBasic's development has seen several major releases that introduced significant features, expanded platform support, and refined its core capabilities. The version 3.00, released on April 4, 2002, marked an important milestone by introducing the PureLibrary system for creating dynamic link libraries (DLLs), support for ElseIf statements in conditional structures, and new libraries for timers and printers, alongside a restructured library architecture to improve modularity and performance.[3]
Subsequent updates quickly broadened its cross-platform reach. Version 3.30, released on August 16, 2002, added initial support for Linux, enabling compilation and execution on Linux systems and establishing PureBasic's early multi-platform foundation beyond Windows.[3] By version 4.00 in 2006, macOS support was introduced, further expanding accessibility to Apple platforms and allowing developers to target a wider range of operating systems with minimal code changes.[3]
Later releases focused on enhancing tools and compatibility. Version 5.00, released in November 2012, improved the integrated development environment (IDE) with an advanced debugger and profiler for better code analysis.[3] The 5.73 LTS edition, dated November 23, 2020, incorporated weak SSL options for HTTP communications to aid compatibility with legacy servers and introduced customizable indentation settings in the IDE for improved code readability.[3]
The transition to version 6.00 LTS on June 22, 2022, represented a substantial overhaul, including an optional C backend for compilation to leverage external toolchains, native support for Apple M1 processors and Raspberry Pi hardware, and optimizations for 64-bit architectures to boost performance on modern systems.[3] Building on this, version 6.10 LTS, released on March 27, 2024, added the WebView library for embedding web content, DPI-aware rendering specifically for macOS to ensure sharp displays on high-resolution screens, and the Skeleton library to facilitate 3D modeling and animation workflows.[3]
The most recent stable release, version 6.21 on June 9, 2025, introduced the #PB_Sprite_Transparent constant for enhanced sprite handling in graphics applications, extended the OSVersion() function to detect Windows Server 2025, and optimized Linux builds by integrating an upgraded GCC compiler for better efficiency and compatibility.[3] Notably, support for AmigaOS was discontinued in 2002, after which version 4.00 was partially open-sourced in 2006 to preserve legacy access.[11][12][13]
Language Features
Core Characteristics and Syntax
PureBasic is a procedural programming language that adheres to BASIC-inspired syntax principles, featuring case-insensitive variable names and line-number-free code structure for enhanced readability and maintainability.[14] Control flow is managed through structured commands such as If...EndIf for conditional statements and For...Next for loops, eliminating the need for GOTO statements common in older BASIC dialects.[15] This design promotes a modern, block-based approach while retaining the simplicity of BASIC, allowing developers to write concise, human-readable code without explicit line numbering.[15]
The language employs a native compiler that generates standalone 32-bit and 64-bit executables directly from source code, requiring no external runtime DLLs or interpreters beyond standard system libraries.[1] These executables are notably compact, typically ranging from 4 to 10 KiB for simple programs like a basic "Hello World" application, owing to the compiler's optimization and inclusion of only necessary library components.[1] PureBasic supports low-level programming constructs, including pointers for direct memory access, user-defined structures via Structure...EndStructure declarations, reusable procedures with Procedure...EndProcedure blocks, and inline assembly code for x86/x64 architectures to enable fine-grained hardware control.[16][17][18]
Variable typing in PureBasic is optional yet encouraged for robustness, with undeclared variables defaulting to the Long type—a 32-bit signed integer—while explicit types such as String can be specified for clarity.[14] The language provides over 1,600 built-in commands spanning file I/O, networking, graphics rendering, and mathematical operations, complemented by full Unicode support for international text handling and module-based namespaces using DeclareModule...EndDeclareModule to organize code and avoid naming conflicts.[1][19][20]
Portability is a core emphasis, enabling the same source code to compile across Windows, Linux, macOS, and Raspberry Pi platforms with minimal platform-specific adjustments, leveraging native code generation for each target.[1] Memory management is manual, eschewing automatic garbage collection in favor of explicit allocation and deallocation through functions like AllocateMemory and FreeMemory, which pair with pointers to give programmers precise control over resources and prevent memory leaks.[21] This approach aligns with the language's focus on performance and efficiency in resource-constrained environments.[21]
Data Types and Variables
PureBasic supports a variety of primitive data types for variables, which can be declared optionally with explicit types or inferred by default as integers. Variables are declared using simple assignment, such as MyVar.l = 42 for a 32-bit signed long integer, and uninitialized variables default to zero. The language enforces case-insensitive naming without leading numbers or special characters, and the EnableExplicit directive requires all variables to be declared before use to prevent errors. Multiple variables can be declared together using Define, assigning the same type unless overridden.[14]
The core primitive types include integers, floating-point numbers, characters, and strings, each with specific sizes and ranges optimized for platform efficiency. Long integers (.l) are always 32-bit signed (-2,147,483,648 to +2,147,483,647), while the generic integer (.i) adapts to platform architecture (32-bit on x86, 64-bit on x64). Floating-point types consist of single-precision float (.f, 32-bit, range ±1.175494e-38 to ±3.402823e+38) and double-precision (.d, 64-bit, range ±2.2250738585072013e-308 to ±1.7976931348623157e+308). Character types handle text: ascii (.a, 8-bit unsigned, 0-255), character (.c, 16-bit unsigned, 0-65,535 for Unicode), unicode (.u, 16-bit unsigned), and word (.w, 16-bit signed, -32,768 to +32,767). Byte (.b) provides 8-bit signed values (-128 to +127), and quad (.q) offers 64-bit signed integers (-9,223,372,036,854,775,808 to +9,223,372,036,854,775,807). The following table summarizes these types:
| Type | Suffix | Size (bits) | Range (Signed) |
|---|
| Byte | .b | 8 | -128 to +127 |
| Ascii | .a | 8 | 0 to +255 (unsigned) |
| Character | .c | 16 | 0 to +65,535 (unsigned) |
| Word | .w | 16 | -32,768 to +32,767 |
| Unicode | .u | 16 | 0 to +65,535 (unsigned) |
| Long | .l | 32 | -2,147,483,648 to +2,147,483,647 |
| Integer | .i | 32/64 | Platform-dependent (32-bit: -2,147,483,648 to +2,147,483,647; 64-bit: -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807) |
| Float | .f | 32 | ±1.175494e-38 to ±3.402823e+38 |
| Quad | .q | 64 | -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807 |
| Double | .d | 64 | ±2.2250738585072013e-308 to ±1.7976931348623157e+308 |
Strings in PureBasic are dynamic Unicode-compatible (.s or suffix), with unlimited length prefixed by a size indicator, or fixed-length via .s{Length} for exact allocation. For example, `MyString.s = "Hello"` or `MyString = "World"declares a string variable. Single characters use .c or .u for Unicode support. Constants are defined with a leading #, such as#PI = 3.14159`, and are replaced at compile-time for fixed values like IDs or settings; they must be declared once globally.[15][14]
Advanced data types include arrays, linked lists, maps, and structures for complex data handling. Arrays are declared with Dim for dynamic sizing, e.g., Dim MyArray.l(10) for 11 long integers (indices 0-10), and can be resized via ReDim; static arrays within structures use [Size]. Linked lists use NewList MyList.s() for ordered dynamic collections, manipulated with AddElement and ForEach. Maps employ NewMap MyMap.s() for key-value pairs, supporting string or numeric keys. Structures define custom types with Structure Person Name.s Age.l EndStructure, allowing field access via \ (e.g., Person\Age), nesting, alignment, and extensions for inheritance-like behavior; they function as object-like containers without native classes. For example:
purebasic
Structure [Person](/page/Person)
Name.s
[Age](/page/Age).l
EndStructure
MyPerson.[Person](/page/Person)
MyPerson\Name = "Alice"
MyPerson\Age = 30
Structure [Person](/page/Person)
Name.s
[Age](/page/Age).l
EndStructure
MyPerson.[Person](/page/Person)
MyPerson\Name = "Alice"
MyPerson\Age = 30
These can include arrays, lists, or maps as fields.[16]
Variable scope is managed via keywords: global declarations with Global make variables accessible program-wide, while Protected limits access to the declaring procedure (reinitialized on calls, akin to local), and Shared enables procedure access to outer-scope variables without global exposure, e.g., Shared Counter inside a procedure references the main Counter. Arrays, lists, and maps follow similar scoping with () suffix for sharing.[22][23]
Type conversions are facilitated by built-in functions and memory operations. Str(Value.q) converts numerics to strings (with variants like StrD for doubles and StrF for formatted floats), while Val(String$) parses strings to quad integers (supporting decimal, hex with $, or binary with %). For low-level access, PeekL(Address) retrieves a long from memory, and PokeL(Address, Value) writes it, with equivalents for other types like PeekB or PokeF; these enable direct type reinterpretation but require careful buffer management to avoid crashes. For instance, Result.l = PeekL(*Buffer) extracts a 32-bit value. These operations support integration with control structures by allowing flexible data manipulation.[24][25][21]
Control Structures and Examples
PureBasic provides essential control structures for managing program flow, including conditional statements, loops, and error handling mechanisms. These structures follow a BASIC-inspired syntax that emphasizes readability and simplicity, allowing developers to implement logic without complex boilerplate code.[26]
Conditional execution is handled through the If...Else...EndIf construct, which evaluates a boolean condition and executes code blocks accordingly. The basic form is If condition : code : Else : alternative code : EndIf, with support for multiple ElseIf clauses for chained conditions. For multi-way branching, PureBasic uses Select...Case...EndSelect, structured as Select expression : Case value : code : [Default : code] : EndSelect, where cases can match exact values, ranges (e.g., Case 1 To 10), or multiple values (e.g., Case 1, 3, 5). This enables efficient handling of switch-like scenarios, with an optional Default case for unmatched values.[26]
Loops in PureBasic include For...Next for counter-based iteration, formatted as For [variable](/page/Variable) = start To end [Step increment] : code : Next, which automatically manages the loop variable and supports positive or negative steps. Indefinite loops use While...Wend (While condition : code : Wend) to repeat while a condition holds true, or Repeat...Until (Repeat : code : Until condition) to execute at least once until the condition becomes true, with an option for infinite loops via Until Forever. These constructs facilitate tasks like array processing or event polling.[26]
Error handling is implemented via OnError...Catch...EndError, which intercepts runtime errors and allows graceful recovery: OnError : code : Catch : recovery code : EndError. This block can redirect to labels or procedures for detailed error management, such as logging or user notifications, preventing abrupt program termination.[26]
A basic "Hello World" program demonstrates these elements minimally:
MessageRequester("Title", "Hello World")
MessageRequester("Title", "Hello World")
This code displays a dialog box and, when compiled as a standalone Windows executable, produces a file of approximately 4.5 KiB, highlighting PureBasic's efficiency in generating compact binaries.[26][27]
For output during development, the Debug command prints to the IDE's debugger window. A simple loop example illustrates iteration and string conversion (referencing string types denoted by .s):
For i = 0 To 9
Debug Str(i)
Next
For i = 0 To 9
Debug Str(i)
Next
This outputs numbers 0 through 9, showcasing For...Next with type conversion via Str().[26]
Procedures encapsulate reusable logic, defined as Procedure name(parameters) : code : EndProcedure, with optional return types like .s for strings. An example greeting procedure is:
Procedure.s Greet(name.s)
ProcedureReturn "Hello " + name
EndProcedure
Debug Greet("User")
Procedure.s Greet(name.s)
ProcedureReturn "Hello " + name
EndProcedure
Debug Greet("User")
Calling Greet("User") outputs "Hello User", demonstrating parameter passing and string concatenation within a control flow context.[26]
Programming Paradigms
Procedural Programming
PureBasic supports procedural programming as its core paradigm, enabling developers to structure code into reusable blocks that promote modularity and maintainability without relying on object-oriented constructs.[17] This approach aligns with established BASIC principles, allowing for straightforward implementation of algorithms through sequential execution and subroutine calls.[26]
Procedures in PureBasic serve as the primary mechanism for encapsulating reusable code, defined using the Procedure keyword followed by an optional return type specifier, such as .l for long integers or .s for strings.[17] The syntax is Procedure[.<type>] Name(Param1[.<type>], Param2[.<type>] [=DefaultValue], ...) followed by the procedure body and concluded with EndProcedure.[17] Within the body, developers can include control structures for flow management, and the procedure can return a value using ProcedureReturn expression, which immediately exits the procedure.[17] For instance, a simple procedure to compute the maximum of two numbers might be written as:
Procedure.l Maximum(nb1.l, nb2.l)
If nb1 > nb2
ProcedureReturn nb1
[Else](/page/The_Else)
ProcedureReturn nb2
EndIf
End[Procedure](/page/Procedure)
Procedure.l Maximum(nb1.l, nb2.l)
If nb1 > nb2
ProcedureReturn nb1
[Else](/page/The_Else)
ProcedureReturn nb2
EndIf
End[Procedure](/page/Procedure)
This returns the larger input value when called, such as Maximum(15, 30) yielding 30.[17]
Parameter passing defaults to by-value semantics for scalar types like integers and strings, ensuring the procedure receives a copy of the argument to avoid unintended modifications to the original data.[17] For pass-by-reference behavior, developers use pointer parameters prefixed with an asterisk, such as *param.l, allowing direct manipulation of the caller's memory.[26] Complex data structures like arrays, lists, and maps are passed by reference inherently when specified in the parameter list, facilitating efficient handling of collections without copying.[17] Optional parameters support default values via constant expressions in the declaration, enabling flexible calls like Procedure Name(param1, param2 = 0), where the second argument defaults to zero if omitted.[17]
Modules enhance procedural organization by isolating code into self-contained units, declared with DeclareModule Name for the public interface (exposing procedures, variables, and structures) and implemented with Module Name for private details.[20] Access to module contents occurs via the Name::Item syntax or by importing the entire module with UseModule Name, which brings public elements into the current scope for direct use.[20] This structure prevents name conflicts and supports code reuse across projects, making it ideal for large-scale development.[20] To remove imported elements and avoid scope pollution, UnuseModule Name can be employed.[20]
Variable scoping in PureBasic distinguishes between global and local declarations to manage data access within procedural contexts.[26] Local variables, declared with Define or implicitly within procedures, are confined to their declaring scope and deallocated upon exit, promoting encapsulation.[28] Global variables, prefixed with Global, remain accessible throughout the program, including across modules if declared publicly.[26] Within modules, the Protected keyword restricts variables to module-internal use, while Shared enables shared access among procedures in a common module when imported via UseModule.[20]
The main program entry point in PureBasic is implicit, consisting of top-level code executed sequentially from the script's beginning, without requiring an explicit Main() procedure.[28] This allows immediate initialization of globals and calls to procedures, often structured around an event loop for interactive applications.[28]
A representative example of a modular procedural program demonstrates separation of concerns with dedicated procedures for initialization, core logic, and cleanup, such as in a file explorer utility.[28] Initialization might create a global list with NewList Files.FILEITEM(), the main loop could examine files via FilesExamine(Folder.s, List Files.FILEITEM()) and handle events in a Repeat...Until structure, and cleanup would free resources upon program termination.[28] This design ensures the top-level code orchestrates procedure calls while keeping implementation details modular.[28]
Object-Oriented Extensions
PureBasic is fundamentally a procedural language without built-in classes, but it supports object-oriented features through native interfaces, enabling inheritance, polymorphism, and method encapsulation.[29] Interfaces are defined using the Interface keyword, optionally extending existing interfaces for inheritance, and declare methods that can be implemented by structures or external objects like COM or DLLs. The syntax is Interface Name [Extends ParentInterface] Method1.Type() ... EndInterface, providing a basis for OOP suitable for advanced users. For example, an interface for a shape might be extended to a colored shape, inheriting methods while adding new ones, allowing polymorphic calls through interface pointers without performance overhead.[29]
Developers can also simulate traditional OOP using structures augmented with procedure pointers to mimic objects and methods, akin to low-level implementations in C.[30] This approach allows for encapsulation of data within structures while associating functions via pointers in a virtual method table (vtable).[31]
Community libraries and precompilers extend these capabilities, providing higher-level abstractions for OOP without altering the core language. Notable examples include the libClass.pbLib, which facilitates class-like definitions through interfaces and structures, supporting constructors (e.g., New() or ConstructorEx()), destructors (e.g., Delete() or De()), and polymorphism via interface extensions.[32] Other frameworks, such as those shared on the PureBasic forums, offer reusable components for virtual tables and inheritance simulation by copying vtable entries between base and derived structures.[31] These libraries are typically distributed in PureLibrary format (.pbLib files), which integrate seamlessly as include files or compiled modules.[33]
A representative example involves defining a "Person" class to simulate encapsulation and methods. A structure might hold instance data like name and age, with a vtable pointer for methods:
Structure sPerson
vtable.*sMethod
name.s
age.i
EndStructure
Structure sMethod
GetName.*GetNameProc()
SetAge.*SetAgeProc(age.i)
Destroy.*DestroyProc()
EndStructure
Procedure.s Person_GetName(*this.sPerson)
ProcedureReturn *this\name
EndProcedure
; Constructor
Procedure *Person_New(name.s, age.i)
*obj.sPerson = AllocateStructure(sPerson)
*obj\vtable = ?PersonVTable
*obj\name = name
*obj\age = age
ProcedureReturn *obj
EndProcedure
DataSection
PersonVTable:
Data.i @Person_GetName()
Data.i @Person_SetAge()
Data.i @Person_Destroy()
EndDataSection
Structure sPerson
vtable.*sMethod
name.s
age.i
EndStructure
Structure sMethod
GetName.*GetNameProc()
SetAge.*SetAgeProc(age.i)
Destroy.*DestroyProc()
EndStructure
Procedure.s Person_GetName(*this.sPerson)
ProcedureReturn *this\name
EndProcedure
; Constructor
Procedure *Person_New(name.s, age.i)
*obj.sPerson = AllocateStructure(sPerson)
*obj\vtable = ?PersonVTable
*obj\name = name
*obj\age = age
ProcedureReturn *obj
EndProcedure
DataSection
PersonVTable:
Data.i @Person_GetName()
Data.i @Person_SetAge()
Data.i @Person_Destroy()
EndDataSection
This creates an object with *person = Person_New("Alice", 30), allowing calls like Debug person\vtable\GetName(person) to retrieve "Alice". Polymorphism can be achieved by overriding vtable entries in derived structures, such as extending to an "Employee" class.[31][32]
Key limitations include manual memory management, requiring explicit allocation (e.g., AllocateStructure()) and deallocation (e.g., FreeStructure()) to avoid leaks, with no garbage collection or automatic vtable resolution.[31] There is also no native support for automatic inheritance chaining or runtime type information beyond interfaces, making complex hierarchies labor-intensive.[32] Despite these constraints, OOP extensions integrate directly with PureBasic's procedural code, allowing hybrid applications where simulated objects coexist with standard procedures and modules.[30]
Integrated Development Environment
PureBasic includes a built-in integrated development environment (IDE) that serves as the primary interface for writing, managing, and executing code, featuring a multi-tabbed editor for handling multiple source files simultaneously. The editor supports syntax highlighting for keywords and braces, with mismatches underlined in red, and provides auto-completion that suggests commands after partial input, selectable via keyboard navigation and insertion with the Tab key. Automatic indentation adjusts based on keywords upon pressing Enter, with options for block or keyword-sensitive modes, and the editor allows code folding using markers like [-]/[+] for hiding sections. Project management enables creation of project files that organize sources, set configurations, and define multiple compile targets for different builds, scanning all files for enhanced auto-completion even when not open.[34][34][35]
The IDE's debugger, introduced as a runtime tool in version 2.10 (February 2001), supports step-through execution modes such as Step (line-by-line), Step Over (skipping procedures), and Step Out (finishing current procedure), along with breakpoints on lines or data conditions. Users can set breakpoints by Alt+clicking lines or via the menu, inspect variables through mouse-over tooltips and dedicated watch lists, and view the call stack during halts, with support for threaded programs and remote debugging over networks. The profiler tool analyzes performance by counting line executions during runs, displaying results in a graph of line numbers versus counts, allowing identification of bottlenecks through start/stop/reset controls and multi-file comparisons with customizable colors.[36][3][37]
Compiler integration allows one-click building via the "Compile/Run" command (F5), which compiles source to an executable and launches it, with options to create standalone executables, DLLs, or bundled applications. Optimization levels include enabling a C code optimizer using GCC flags like -O2, alongside CPU-specific settings, and since version 6.00 (June 2022), users can select between the traditional assembly (ASM) backend or a new C backend for broader platform support. For non-GUI projects, the IDE supports console mode compilation, producing text-based executables that run without a graphical interface, suitable for command-line applications. The IDE also integrates with the Form Designer as an extension for visual interface creation.[38][3]
Preferences provide extensive customization, including themes with default and user-added options via zip files containing images and settings, adjustable indentation (spaces or tabs, with length control), and fully reconfigurable keyboard shortcuts, though some like Tab for indentation are reserved. Multi-language support allows switching the IDE interface to languages such as English and French through a preferences menu, enhancing accessibility for international users.[39][39]
The PureBasic integrated development environment (IDE) includes a form designer that facilitates rapid application development (RAD) for graphical user interfaces (GUIs) through a drag-and-drop interface. This tool enables developers to visually create windows and position gadgets such as buttons, list views, images, and canvases directly on the form surface, streamlining the layout process without manual coordinate calculations.[40]
Supported gadgets encompass a range of native UI elements, including ButtonGadget for interactive controls, ListViewGadget for displaying tabular data, CanvasGadget for custom 2D drawing and event handling, as well as menus and status bars. The designer generates procedural code automatically upon placement, such as CreateGadgetList() to initialize the gadget hierarchy and ButtonGadget(0, 100, 100, 200, 30, "Click Me") to define a button's position, size, and text, which can be edited or extended in the IDE.[40][41]
Event handling is managed through a main event loop in the generated code, utilizing functions like ExamineEvents() to poll for user interactions and WaitWindowEvent() to maintain window responsiveness, with automatic procedure stubs for specific events such as button clicks (e.g., OkButtonEvent). Forms can be exported as .pbf files for reuse across projects, allowing modular integration via XIncludeFile and compatibility with PureBasic's 2D libraries like Sprite for graphics or external 3D engines such as OGRE through CanvasGadget extensions.[40][42]
While the form designer produces cross-platform compatible code that leverages native OS GUI components on Windows, Linux, macOS, and Raspberry Pi, its visual preview and gadget rendering are optimized for Windows, requiring adaptations for platform-specific styling on other operating systems.[40][41]
Supported Operating Systems
PureBasic primarily targets desktop and embedded operating systems, providing native compilation support for Windows, Linux, macOS, and Raspberry Pi OS across various architectures.[26] The language generates optimized executables without requiring virtual machines or interpreters, ensuring compatibility with standard system libraries on these platforms.[1]
On Windows, PureBasic supports x86 (32-bit), x64 (64-bit), and ARM64 architectures, with the latter introduced in version 6.20 released in February 2025.[3] It offers full compatibility with Windows Server editions, including versions up to 2025, as added in version 6.21 in June 2025.[3]
For Linux, support includes x86 and x64 architectures on distributions such as Ubuntu 24.04, which received dedicated packaging in version 6.12 in September 2024.[3] Additionally, ARM32 and ARM64 are supported specifically for Raspberry Pi OS, enabling embedded applications since version 6.00 in June 2022.[3]
macOS compatibility covers x64 and Apple Silicon (M1 and later) processors, with native ARM64 support added in version 6.00 in June 2022.[43] DPI-aware rendering for high-resolution displays was implemented starting with version 6.10.[43] Version 6.12 also ensures compatibility with macOS 15 (Sequoia).[3]
AmigaOS support has been discontinued, though partial open-source components were released after version 4.00 around 2006, allowing limited community maintenance.[10]
PureBasic does not provide official support for mobile platforms like iOS or Android, though its console mode can be adapted for basic command-line applications on such systems via third-party tools.[5] Raspberry Pi integration further extends its use in embedded and IoT scenarios.[3]
PureBasic enables single-source portability across supported platforms, allowing developers to write code once and compile it for different operating systems by selecting the target in the integrated development environment (IDE). This process requires minimal use of preprocessor directives, such as CompilerIf #PB_Compiler_OS = #PB_OS_Windows for OS-specific sections, to handle variations like API calls or file paths, ensuring broad compatibility without extensive rewriting.[44]
The compiler supports two backends: the traditional assembly (ASM) output, which generates optimized machine code directly, and a C backend introduced in version 6.00 (June 2022) for enhanced optimization, particularly on non-Windows platforms. The C backend leverages external compilers like GCC with flags such as -O2 for performance tuning, while the ASM backend allows inline x86 assembly for fine-grained control, though it is disabled in C mode. Developers can specify the backend using directives like #PB_Backend_C to balance portability and speed.[44][43]
Resulting executables are standalone binaries that do not require external runtime libraries or DLLs, promoting easy deployment and reducing dependencies. These binaries are notably compact—for instance, a basic "Hello World" program compiles to approximately 4 KiB—while maintaining high execution speed comparable to languages like C++. Options for CPU-specific optimization (e.g., dynamic CPU detection) and thread safety further enhance performance without increasing size significantly.[10][38]
For packaging, PureBasic includes a built-in packer library supporting formats like ZIP and LZMA for compressing data or creating archives within applications, which can be integrated to bundle resources efficiently. Additionally, the PureLibrary feature allows creation of reusable modules compiled as platform-appropriate shared libraries (DLL on Windows, .so on Linux, .dylib on macOS), enabling modular code distribution and extension of the core command set.[45][33]
Deployment is straightforward, with executables supporting both console and graphical user interface (GUI) modes that run directly on the target system. For 3D applications, native integration with the OGRE engine provides robust rendering capabilities, while community wrappers extend support to alternatives like Irrlicht. Platform-specific challenges, such as differing APIs (e.g., WinAPI on Windows versus Cocoa on macOS), are managed through dedicated libraries that abstract these differences, minimizing cross-platform friction.[46]
Community and Ecosystem
User Community and Support
The PureBasic user community is centered around official forums hosted by Fantaisie Software, providing platforms for discussion, troubleshooting, and sharing code. The official English-language forum, accessible at https://www.purebasic.fr/english/, serves as the primary hub for international users and features sections for coding questions, tricks and tips, game programming, and general discussions; as of November 2025, it had 6,575 registered members, 71,467 threads, and 590,275 posts.[47] A parallel French forum at https://www.purebasic.fr/french/ caters mainly to non-English speakers, offering tutorials, announcements, and localized support resources.[48]
Support for PureBasic is structured around direct assistance for licensed users via an email-based system at [email protected], which functions as a ticket mechanism for queries and issue resolution. Lifetime licenses include free updates to all future versions, ensuring ongoing access without additional costs after initial purchase.[5]
Users frequently contribute practical code examples and solutions within forum threads, fostering collaborative problem-solving. The user base primarily comprises hobbyists, independent game developers, and educators, with steady growth since the language's inception around 2000.[47]
Official documentation supports the community through a comprehensive reference manual available in both PDF and HTML formats, detailing all commands, libraries, and usage guidelines. Community members also share extensions to enhance functionality, often discussed in forum sections dedicated to libraries and tools.[49]
Libraries, Extensions, and Resources
PureBasic includes 67 built-in modules that provide specialized functionality for common programming tasks, enabling developers to handle complex operations without external dependencies.[49] These modules are integrated directly into the language and cover diverse domains such as security, data persistence, communication protocols, and visual rendering. For instance, the Cipher module supplies algorithms for encryption and decryption, supporting standards like AES and RSA to secure data in applications.[50]
The Database module facilitates interaction with SQLite databases, allowing for embedded SQL queries, table management, and transaction handling within PureBasic programs.[51] In networking, the Network module supports TCP and UDP protocols for client-server communication, while the FTP module extends this to include SFTP for secure file transfers over SSH, a feature introduced in version 6.12.[52][53][43] For graphics, the Sprite module enables 2D sprite manipulation and animation, ideal for game development, and the Engine3D module leverages the OGRE 3D rendering engine for advanced 3D scene management, including lighting, materials, and physics integration via the Bullet library.[46][54]
Beyond built-in options, the community has developed extensions to address specific needs, such as the Irrlicht wrapper, which provides bindings to the Irrlicht 3D engine for lightweight scene rendering and real-time simulations.[55] The WebView library, integrated as a built-in module since version 6.10, allows embedding modern web browsers using native OS components like WebView2 on Windows, enabling HTML/CSS-based user interfaces within PureBasic applications.[56][43] For object-oriented enhancements, community efforts extend procedural code with class-like structures using PureBasic's interface system.[29]
PureBasic supports the creation of PureLibraries, a format for compiling user-defined extensions as dynamic link libraries (DLLs) that can be shared across projects.[33] These libraries allow developers to package reusable code, such as mathematical utilities for vector calculations or wrappers for game engines, and distribute them as binary files with optional source inclusion. Examples include custom modules for advanced audio processing or cross-platform utilities, which integrate seamlessly without altering the core compiler.[33]
Key resources for developers include the official reference manual, available as PureBasic.pdf and updated with each version release to document commands, modules, and best practices.[26] Open-source components, particularly for platforms like AmigaOS, are hosted on GitHub repositories maintained by the developers, providing access to source code for customization and analysis.[57] Third-party educational materials, such as the book PureBasic - A Beginner's Guide to Computer Programming (2006), offer introductory tutorials on leveraging these libraries for practical applications.[58]
Extensions and libraries are loaded into programs using directives like IncludeFile for simple script inclusion or UseModule for modular code organization, promoting code reuse without namespace conflicts.[59][20] While PureBasic lacks a formal package manager, libraries are typically obtained through forum downloads or direct compilation from shared sources. Since establishing public GitHub repositories in 2019, the project has encouraged community contributions for enhancements, including new modules and platform-specific improvements.[57][60]