{"article":{"slug":"dynamic-packages-for-free-pascal-and-lazarus","title":"Dynamic Packages for Free Pascal and Lazarus","subtitle":null,"summary":"The getlazarus.org maintainer announces the first release of full dynamic package support for the Free Pascal Compiler and Lazarus IDE, letting components and plugins be built as shared libraries and installed without rebuilding the IDE, and covers restrictions, runtime changes, IDE improvements and how to help.","content_type":"announcement","language":"en","canonical_url":"https://www.getlazarus.org/dynamic/","author":{"name":"sysrpl","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"getlazarus.org","url":"https://www.getlazarus.org/","listing_slug":null,"listing":null},"topics":[{"name":"Programming","slug":"programming","url":"https://listedarticles.com/topics/programming"},{"name":"Programming Languages","slug":"programming-languages","url":"https://listedarticles.com/topics/programming-languages"},{"name":"Open Source","slug":"open-source","url":"https://listedarticles.com/topics/open-source"},{"name":"Compilers","slug":"compilers","url":"https://listedarticles.com/topics/compilers"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":1157,"reading_minutes":5,"published_at":"2026-10-18T20:12:21.105Z","added_at":"2026-10-18T20:12:21.105Z","updated_at":"2026-10-18T20:12:21.105Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/dynamic-packages-for-free-pascal-and-lazarus","markdown_url":"https://listedarticles.com/articles/dynamic-packages-for-free-pascal-and-lazarus.md","example":false,"citation":"sysrpl, getlazarus.org. \"Dynamic Packages for Free Pascal and Lazarus.\" 18 Oct 2026. https://www.getlazarus.org/dynamic/ (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://www.getlazarus.org/dynamic/"},"body_markdown":"# Dynamic Packages\n\nI am pleased to announce the first release of full dynamic package support for the Free Pascal Compiler and the Lazarus IDE. This feature has been a long time coming for the ecosystem, but a complete implementation is now available for [download](https://www.getlazarus.org/setup) from this website.  \n  \nDynamic packages allow users to create and install components, controls, and Lazarus extensions in seconds without rebuilding the entire IDE. They can also be used in your own programs to develop and deploy plugins that expose native Pascal classes and types through dynamic package libraries. To support this functionality, I have made numerous improvements to the compiler, its runtime, and the Lazarus IDE. I have also created additional IDE extensions to improve the experience of working with Lazarus packages.  \n\n[All installers include dynamic package support](https://www.getlazarus.org/setup)\n\nDynamic packages are implemented as standard shared library files for Linux, Windows, and macOS. They contain additional metadata generated by the compiler that can be inspected and queried using new RTL units. The runtime also includes mechanisms for safely preserving thread variables and managing dynamic types, such as strings and dynamic arrays, between programs and packages or between multiple packages.  \n  \n\nVideo: Dynamic Packages Example\n\n  \nWhen deploying your program, you can still bundle everything into a single executable. Alternatively, you can divide it into multiple dynamic packages that can be replaced while your program is running, providing a plugin system.  \n\n## Restrictions\n\nDynamic packages come with a few restrictions. First, a unit contained in a package cannot have the same name as the package itself. I have enhanced the default package system so that the generated Pascal source file automatically appends the word Package to the package name. For example, if you create a package called\n\nElectroTools.lpk\n\n, the source file listing all the units contained in the package will be named\n\nElectroToolsPackage.pas\n\ninstead of\n\nElectroTools.pas\n\n.  \n  \nAnother restriction is that unit names must be unique across packages. If someone else has written a unit named Widgets, you cannot install another package containing a unit with the same name. You must either choose which package to install or rename one of the conflicting units.  \n  \nDynamic packages are also larger than ordinary shared libraries because they contain a map of everything inside them. Stripping a dynamic package removes the metadata required for it to function as a dynamic package.  \n\n## RTL Enhancements\n\n```\ntype\n  TPackageType = record\n    { The unit that declares the type }\n    UnitName: string;\n    { The name of the type }\n    Name: string;\n    { The kind of the type }\n    Kind: TTypeKind;\n    { The RTTI of the type }\n    Info: PTypeInfo;\n    { The class if Kind is tkClass, otherwise nil }\n    ClassType: TClass;\n  end;\n```\n\nThe runtime library has been enhanced to support dynamic packages, including the metadata required to inspect their contents and the mechanisms needed to safely manage dynamic types and thread variables across package boundaries.  \n  \nA new unit\n\nDynPkgTypes.pas\n\nhas been added to the RTL to help you with reading information from dynamic packages. The same tried and true RTTI information can be gather from a package to work with its contents. There are enough functions in the RTL to work with dynamic packages to do everything you need, including loading, enumerating, searching, and unloading packages at runtime.  \n\n## Lazarus Enhancements\n\nI have made several enhancements to the Lazarus IDE to take better advantage of dynamic packages.  \n  \nThe first thing you will notice when you open Lazarus is a new progress window that can appear outside the IDE. When you modify source code belonging to a package registered with the IDE, the system detects the changes and automatically rebuilds the package before Lazarus starts. While this is happening, a progress window notifies you that changes have been detected and the package is being rebuilt.  \n  \nThe same window appears when you choose to rebuild the entire IDE. It remains visible and displays information about the current operation, including the estimated time remaining before the IDE restarts. The progress window also appears when adding or removing packages if the operation takes more than five seconds. This can happen when installing multiple packages at once, which is another new feature.  \n  \nAnother enhancement is a new Packages window, docked on the right by default. It displays the packages you have recently opened, and the list persists between Lazarus sessions. You can browse the files within a package and double click an item to open it.  \n  \nWhen you open an installed package and click Compile in its package window, any associated controls, components, or extensions are updated within a second or two. This significantly speeds up development because changes that previously required rebuilding the entire IDE can now be applied almost immediately.  \n  \nThe package menu, which lists available packages, has also been improved. Adding or removing packages now updates the IDE without requiring a rebuild.  \n  \nPackage options have been extended as well. Under IDE Integrations, you can now restrict a package to a specific platform or widgetset. If a package does not meet the current platform or widgetset requirements, it will not appear in the package list. The IDE will also ignore the package when it detects changes or would otherwise attempt to open it.  \n  \nFor example, suppose you develop a TWinControl implementation for the Windows IShellView COM interface. You can restrict the package so that it is available only when Lazarus is running on Windows.  \n  \nAnother enhancement I created to demonstrate the capabilities of dynamic packages is a new form or frame conversion feature for Lazarus extensions. It converts any form or frame into an installable control that is automatically added to the component palette. All controls, events, methods, and properties are copied to the new control.  \n  \nThis makes it possible to visually design and lay out new controls or easily reuse existing forms and frames in other projects.  \n  \n**Note:** If you attempt to build a package that is currently being used by an open form, the IDE will ask you to save or close the form before building the package.  \n  \nThese features and more are available for download now at the location linked below. The complete changes to FPC and Lazarus have been committed to GitLab in my forked branch named dynamic packages.  \n\n[FPC dynamic package branch](https://gitlab.com/sysrpl/fpc)\n[Lazarus dynamic package branch](https://gitlab.com/sysrpl/fpc)\n\nIf you encounter any problems, please report them through the GitLab issue tracker associated with the branches linked above. If you would like to discuss dynamic packages or ask questions, you can use the forum linked below. Please note that a moderator must approve your account before you can create new posts.  \n\n## Helping Out\n\nIf you would like to help with this project, the site needs moderators. You can send me (sysrpl) a private message if you are interested in contributing.  \n  \nI am also having difficulty working on macOS and producing the necessary builds. If anyone has an M1 Macintosh they would be willing to donate, please send me a private message. I would really like to work on the compiler code needed to support dynamic packages on the M1 architecture.\n","body_html":"<h1 id=\"dynamic-packages\">Dynamic Packages</h1>\n<p>I am pleased to announce the first release of full dynamic package support for the Free Pascal Compiler and the Lazarus IDE. This feature has been a long time coming for the ecosystem, but a complete implementation is now available for <a href=\"https://www.getlazarus.org/setup\" rel=\"nofollow ugc noopener\">download</a> from this website.  </p>\n<p>Dynamic packages allow users to create and install components, controls, and Lazarus extensions in seconds without rebuilding the entire IDE. They can also be used in your own programs to develop and deploy plugins that expose native Pascal classes and types through dynamic package libraries. To support this functionality, I have made numerous improvements to the compiler, its runtime, and the Lazarus IDE. I have also created additional IDE extensions to improve the experience of working with Lazarus packages.  </p>\n<p><a href=\"https://www.getlazarus.org/setup\" rel=\"nofollow ugc noopener\">All installers include dynamic package support</a></p>\n<p>Dynamic packages are implemented as standard shared library files for Linux, Windows, and macOS. They contain additional metadata generated by the compiler that can be inspected and queried using new RTL units. The runtime also includes mechanisms for safely preserving thread variables and managing dynamic types, such as strings and dynamic arrays, between programs and packages or between multiple packages.  </p>\n<p>Video: Dynamic Packages Example</p>\n<p>When deploying your program, you can still bundle everything into a single executable. Alternatively, you can divide it into multiple dynamic packages that can be replaced while your program is running, providing a plugin system.  </p>\n<h2 id=\"restrictions\">Restrictions</h2>\n<p>Dynamic packages come with a few restrictions. First, a unit contained in a package cannot have the same name as the package itself. I have enhanced the default package system so that the generated Pascal source file automatically appends the word Package to the package name. For example, if you create a package called</p>\n<p>ElectroTools.lpk</p>\n<p>, the source file listing all the units contained in the package will be named</p>\n<p>ElectroToolsPackage.pas</p>\n<p>instead of</p>\n<p>ElectroTools.pas</p>\n<p>.  </p>\n<p>Another restriction is that unit names must be unique across packages. If someone else has written a unit named Widgets, you cannot install another package containing a unit with the same name. You must either choose which package to install or rename one of the conflicting units.  </p>\n<p>Dynamic packages are also larger than ordinary shared libraries because they contain a map of everything inside them. Stripping a dynamic package removes the metadata required for it to function as a dynamic package.  </p>\n<h2 id=\"rtl-enhancements\">RTL Enhancements</h2>\n<pre><code>type\n  TPackageType = record\n    { The unit that declares the type }\n    UnitName: string;\n    { The name of the type }\n    Name: string;\n    { The kind of the type }\n    Kind: TTypeKind;\n    { The RTTI of the type }\n    Info: PTypeInfo;\n    { The class if Kind is tkClass, otherwise nil }\n    ClassType: TClass;\n  end;</code></pre>\n<p>The runtime library has been enhanced to support dynamic packages, including the metadata required to inspect their contents and the mechanisms needed to safely manage dynamic types and thread variables across package boundaries.  </p>\n<p>A new unit</p>\n<p>DynPkgTypes.pas</p>\n<p>has been added to the RTL to help you with reading information from dynamic packages. The same tried and true RTTI information can be gather from a package to work with its contents. There are enough functions in the RTL to work with dynamic packages to do everything you need, including loading, enumerating, searching, and unloading packages at runtime.  </p>\n<h2 id=\"lazarus-enhancements\">Lazarus Enhancements</h2>\n<p>I have made several enhancements to the Lazarus IDE to take better advantage of dynamic packages.  </p>\n<p>The first thing you will notice when you open Lazarus is a new progress window that can appear outside the IDE. When you modify source code belonging to a package registered with the IDE, the system detects the changes and automatically rebuilds the package before Lazarus starts. While this is happening, a progress window notifies you that changes have been detected and the package is being rebuilt.  </p>\n<p>The same window appears when you choose to rebuild the entire IDE. It remains visible and displays information about the current operation, including the estimated time remaining before the IDE restarts. The progress window also appears when adding or removing packages if the operation takes more than five seconds. This can happen when installing multiple packages at once, which is another new feature.  </p>\n<p>Another enhancement is a new Packages window, docked on the right by default. It displays the packages you have recently opened, and the list persists between Lazarus sessions. You can browse the files within a package and double click an item to open it.  </p>\n<p>When you open an installed package and click Compile in its package window, any associated controls, components, or extensions are updated within a second or two. This significantly speeds up development because changes that previously required rebuilding the entire IDE can now be applied almost immediately.  </p>\n<p>The package menu, which lists available packages, has also been improved. Adding or removing packages now updates the IDE without requiring a rebuild.  </p>\n<p>Package options have been extended as well. Under IDE Integrations, you can now restrict a package to a specific platform or widgetset. If a package does not meet the current platform or widgetset requirements, it will not appear in the package list. The IDE will also ignore the package when it detects changes or would otherwise attempt to open it.  </p>\n<p>For example, suppose you develop a TWinControl implementation for the Windows IShellView COM interface. You can restrict the package so that it is available only when Lazarus is running on Windows.  </p>\n<p>Another enhancement I created to demonstrate the capabilities of dynamic packages is a new form or frame conversion feature for Lazarus extensions. It converts any form or frame into an installable control that is automatically added to the component palette. All controls, events, methods, and properties are copied to the new control.  </p>\n<p>This makes it possible to visually design and lay out new controls or easily reuse existing forms and frames in other projects.  </p>\n<p><strong>Note:</strong> If you attempt to build a package that is currently being used by an open form, the IDE will ask you to save or close the form before building the package.  </p>\n<p>These features and more are available for download now at the location linked below. The complete changes to FPC and Lazarus have been committed to GitLab in my forked branch named dynamic packages.  </p>\n<p><a href=\"https://gitlab.com/sysrpl/fpc\" rel=\"nofollow ugc noopener\">FPC dynamic package branch</a>\n<a href=\"https://gitlab.com/sysrpl/fpc\" rel=\"nofollow ugc noopener\">Lazarus dynamic package branch</a></p>\n<p>If you encounter any problems, please report them through the GitLab issue tracker associated with the branches linked above. If you would like to discuss dynamic packages or ask questions, you can use the forum linked below. Please note that a moderator must approve your account before you can create new posts.  </p>\n<h2 id=\"helping-out\">Helping Out</h2>\n<p>If you would like to help with this project, the site needs moderators. You can send me (sysrpl) a private message if you are interested in contributing.  </p>\n<p>I am also having difficulty working on macOS and producing the necessary builds. If anyone has an M1 Macintosh they would be willing to donate, please send me a private message. I would really like to work on the compiler code needed to support dynamic packages on the M1 architecture.</p>","headings":[{"level":1,"text":"Dynamic Packages","id":"dynamic-packages"},{"level":2,"text":"Restrictions","id":"restrictions"},{"level":2,"text":"RTL Enhancements","id":"rtl-enhancements"},{"level":2,"text":"Lazarus Enhancements","id":"lazarus-enhancements"},{"level":2,"text":"Helping Out","id":"helping-out"}]}}