CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC for Windows, Linux and MacOS.
CEF4Delphi is based on DCEF3 and fpCEF3, which were using outdated branches of CEF. In order to have Chromium-based web browser tabs in BriskBard it's necessary to use the latest stable branch of CEF and have frequent updates. DCEF3 hasn't been updated for a long time so it was decided to create a new project.
The main goal of CEF4Delphi is to simplify, whenever is possible, the work necessary to upgrade it to the latest version of CEF. To achieve this goal it was necessary to take the following measures :
The latest version of CEF4Delphi uses the branch 7049 of CEF. More precisely, it uses CEF 135.0.22 which includes Chromium 135.0.7049.115
CEF4Delphi is developed on Delphi 12.3 and it has also been tested in Delphi 6, Delphi XE, Delphi 10, Delphi 11 and Lazarus 3.8 with FPC 3.2.2. CEF4Delphi includes VCL, FireMonkey (FMX) and Lazarus components tested in 32 and 64 bits.
If you wish to test CEF4Delphi consider downloading the latest Delphi Community Edition from Embarcadero for free.
It's also possible to test CEF4Delphi downloading Lazarus/FPC for free.
Before using CEF4Delphi with an aplication made with Delphi or Lazarus it's necessary to understand that CEF4Delphi is a wrapper that uses CEF's C API and, in turn, CEF insulates the user from the underlying Chromium and Blink code complexity.
The master branch in the repository is considered a development branch and it may have issues. Use the latest released version if you need a stable component.
CEF4Delphi project :
Chromium Embedded Framework (CEF) project :
CEF binaries used by CEF4Delphi :
OldCEF4Delphi project :
Chromium project :
CEF4Delphi can be used in VCL, FMX and LCL applications with Delphi or Lazarus/FPC.
For more information about CEF4Delphi on Lazarus read this wiki page.
Google announced that they would drop Windows XP support for Chrome in 2015. The last CEF branch that was compatible with Windows XP was 2623, released in 2016.
Google also announced that Chromium would not support Windows 7, 8.0 or 8.1 in 2022. The last version of CEF with Windows 7 support was CEF 109 and this is the last CEF4Delphi release with Windows 7 support.
Since CEF4Delphi uses the latest CEF branch, it's not compatible with Windows 7, 8/8.1, XP, Windows Vista, Windows Server 2003, Windows Server 2008 and Windows Server 2012.
CEF4Delphi needs Windows 10, 11 or newer to make it work but if you need to test some other Windows version just download and try to run the CEF Sample Application from the CEF's downloads page.
If you need to support Windows XP and Vista in your app use OldCEF4Delphi.
Linux is fully supported by CEF4Delphi with Firemonkey and Lazarus/FPC in x86 and ARM CPUs.
In the case of Linux applications CEF requires Ubuntu 16.04 or newer.
MacOS is also fully supported by CEF4Delphi with Firemonkey and Lazarus/FPC in x86 CPUs.
CEF4Delphi has not been tested in MacOS with ARM CPUs. CEF requires MacOS 10.11 or newer to run.
To build and install CEF4Delphi in Delphi XE2, XE3, XE4, XE6, XE7, XE8, 10, 11 or 12 you need to follow these steps :
To compile and install CEF4Delphi in Delphi 6, 7, 8, 2005, 2006, 2007, 2009, 2010 or XE you need to follow these steps :
To compile and install CEF4Delphi in Lazarus you need to install the DCPCrypt package first using the Online Package Manager. Then follow these steps :
Before going into the coding details let’s take a moment to build one of the demos to see a working CEF browser.
Build this demo depending on the IDE you use :
In a few seconds you’ll see a new executable inside the CEF4Delphi/bin directory called MiniBrowser.exe or SimpleBrowser2.exe but if you try to run the new EXE it will show an error message with a list of missing CEF binaries.
You need to copy the CEF binaries to the CEF4Delphi/bin directory and you can download them using these links :
Once you've downloaded and decompressed the package you must copy the contents of the Release and Resources directories to the CEF4Delphi/bin directory.
The final layout looks like this :
Notice how cef_sandbox.lib and libcef.lib can be omitted.
If everything is in place you should be able to run the demo.
Build this demo depending on the IDE you use :
If you use Lazarus you will see a new MiniBrowser executable in the CEF4Delphi/bin directory but if you use Delphi you'll need to deploy the executables in order to copy them to a subdirectory inside paserver/scratch-dir/Username-ConnectionProfileName
.
As with the Windows demos, you need to download the CEF binaries using these links :
Decompress the package and copy the contents of the Release and Resources directories to the CEF4Delphi/bin directory in case of Lazarus.
If you use Delphi you'll have decompress the package and copy the contents of the Release and Resources directories to the $HOME/cef
directory. The FMXExternalPumpBrowser2_sp executable found in the paserver/scratch-dir/Username-ConnectionProfileName/FMXExternalPumpBrowser2_sp/
directory also needs to be copied to $HOME/cef
.
The final layout looks like this :
Notice that the libcef.so file is huge because it includes the debug symbols. Running the demo with that libcef.so file will take a few seconds due to its size. In order to reduce the file size and improve the loading time you can remove the debug symbols with the following command :
strip libcef.so
If the CEF binaries are in the right place you should be able to run the demo now.
If you use Lazarus build the Lazarus_Mac/ExternalPumpBrowser and the Lazarus_any_OS/AppHelper demo projects.
At this point you should see 2 new app bundles in the CEF4Delphi/bin directory corresponding to those 2 projects.
Download the CEF binaries package using this link : MacOS x86 (64 bit)
MacOS app bundles must have the right directory structure and contents. In this case you have to decompress the CEF binaries package and copy the contents of Release/Chromium Embedded Framework.framework directory into the ExternalPumpBrowser.app/Contents/Frameworks/Chromium Embedded Framework.framework/ directory.
The AppHelper app must be included inside the ExternalPumpBrowser app and to do that you need to execute the Lazarus_any_OS/AppHelper/create_mac_helper_apps.sh script with the complete path to ExternalPumpBrowser.app as the script argument.
The final layout looks like this :
ExternalPumpBrowser.app/
Contents/
Frameworks/
Chromium Embedded Framework.framework/
Chromium Embedded Framework
Libraries/
libEGL.dylib
libGLESv2.dylib
libswiftshader_libEGL.dylib
libswiftshader_libGLESv2.dylib
libvk_swiftshader.dylib
vk_swiftshader_icd.json
Resources/
chrome_100_percent.pak
chrome_200_percent.pak
resources.pak.pak
Info.plist
icudtl.dat
snapshot_blob.bin
v8_context_snapshot.x86_64.bin
en.lproj/
locale.pak
es.lproj/
locale.pak
****.lproj/
locale.pak
ExternalPumpBrowser Helper.app/
Contents/
Info.plist
MacOS/
ExternalPumpBrowser Helper
Pkginfo
ExternalPumpBrowser Helper (GPU).app/
Contents/
Info.plist
MacOS/
ExternalPumpBrowser Helper (GPU)
Pkginfo
ExternalPumpBrowser Helper (Plugin).app/
Contents/
Info.plist
MacOS/
ExternalPumpBrowser Helper (Plugin)
Pkginfo
ExternalPumpBrowser Helper (Renderer).app/
Contents/
Info.plist
MacOS/
ExternalPumpBrowser Helper (Renderer)
Pkginfo
ExternalPumpBrowser Helper (Alerts).app/
Contents/
Info.plist
MacOS/
ExternalPumpBrowser Helper (Alerts)
Pkginfo
Info.plist
MacOS/
ExternalPumpBrowser
Pkginfo
Resources/
binding.html, ...
If the CEF binaries are correctly copied into the ExternalPumpBrowser app bundle and the create_mac_helper_apps.sh script run without errors then you should be able to run the demo.
In case you use Delphi open the Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowserGroup.groupproj
file, build all the projects in that group and use the Deployment window for each project to copy the app bundle in the remote system.
Decompress the CEF binaries package and copy the contents of Release/Chromium Embedded Framework.framework directory into the paserver/scratch-dir/Username-ConnectionProfileName/Chromium Embedded Framework.framework
directory.
When you run the main project of the project group it will copy the CEF binaries and all the other app bundles corresponding to the helper projects inside FMXExternalPumpBrowser.app/Contents/Frameworks/
automatically.
Before you use CEF4Delphi for the first time it's highly recommended to read all the information about CEF and the design documents of Chromium.
The CEF API documents are available at magpcss.org and there is extensive information about the CEF usage in its source code comments.
As you can see in the documentation, by default CEF uses multiple threads and processes to protect the overall application from bugs and glitches in the rendering engine.
In order to create the child processes, CEF can run the application's executable again or we can configure CEF to use a different executable.
By default, CEF will use the same executable but this can be problematic if the application has a complex initialization or the operating system has other requirements.
CEF4Delphi simplifies all CEF initialization thanks to GlobalCEFApp, which is an instance of the TCEFApplication class.
Windows applications can configure CEF to use one EXE file for all processes or a different EXE for the CEF subprocesses.
If you decide to use the same EXE for all processes then you need to modify the project file (*.DPR in Delphi and *.LPR in Lazarus) to create GlobalCEFApp, set its properties and call GlobalCEFApp.StartMainProcess before the Application.Initialize call.
Let's go into the details using a Delphi project file as an example, The Lazarus project files are almost identical.
Delphi applications use to have this code in the DPR file :
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
To include CEF4Delphi you would need to modify it like this :
program Project1;
uses
Vcl.Forms,
WinApi.Windows,
uCEFApplication,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
begin
GlobalCEFApp := TCefApplication.Create;
if GlobalCEFApp.StartMainProcess then
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
GlobalCEFApp.Free;
end.
The differences are these :
usesclause has a reference to uCEFApplication.
Applicationinstance is initialized and run.
The main process will execute the code in the project file following these steps :
initializationsections in all the units declared in the
usesclause are executed.
Applicationto be initialized and run.
finalizationsections in all the units declared in the
usesclause are executed.
However, the CEF subprocesses will execute the code in the project file following these steps :
initializationsections in all the units declared in the
usesclause are executed.
Application.
finalizationsections in all the units declared in the
usesclause are executed.
If you're adding a CEF browser to an existing application and you need to decide if you can use the same EXE or a different EXE for the CEF subprocesses then you have to check what code is already in the application's project file and the initialization
and finalization
sections because it will be executed once for each process.
If moving all the existing code out of the initialization
and finalization
sections and moving the existing code in the project file is too complicated or it's not allowed then you can use a different EXE for the CEF subprocesses.
In this case, you can create GlobalCEFApp at any moment in your application's lifetime.
Using a different EXE allows your application to initialize CEF only if the user needs to see a web browser but you have to remember that CEF can only be initialized once per process. This is a CEF feature and there's no workaround.
See these demos for all the details :
Using CEF4Delphi in Linux has a few differences with Windows and it can use almost the same code. Read the usage guidelines for Windows before reading this section.
Lazarus demos must add UseCthreads
to the custom options in the project options window.
All the Lazarus demos use GTK 2 and the Delphi demo use GTK 3. QT is not supported at the moment.
Chromium should be initialized in a process with one thread and this can cause issues sometimes because GTK creates some threads when it's initialized.
Lazarus initializes GTK in the Initialization
section of the Interfaces
unit and Delphi initializes GTK in the Initialization
section of the FMX.Platform
unit.
The Initialization
sections are executed before the project file code and this may create problems with CEF.
Lazarus demos can avoid this problem in two ways :
Interfacesunit that moves the GTK initialization away from the
Initializationsection.
Initializationsection and add it to the
usesclause of the project file before the
Interfacesunit.
Delphi demos use FMXLinux and you need to create a custom unit that creates GlobalCEFApp in its Initialization
section and then add it to the uses
clause in the first place.
See these demos for all the details :
Applications with CEF browsers in MacOS must contain 5 Helper app bundles for the subprocesses. Chromium searches for them internally when it needs to create a new subprocess. Read this for more information.
The Helper apps must be in the <appname>.app/Contents/Frameworks
directory and they must have these names :
The 5 Helper applications are identical copies with different name and they only need to create GlobalCEFApp, call GlobalCEFApp.InitLibLocationFromArgs, call GlobalCEFApp.StartSubProcess and destroy GlobalCEFApp.
Read the code comments in the following demos for more details :
CEF can be configured to create web browsers in several ways :
normalmode (a.k.a.
windowedmode) : CEF will create a child control to draw the web contents by itself and many other features and events are also handled internally by CEF.
off screen renderingmode (a.k.a.
OSRmode) : CEF will return a pixel buffer with the web contents. The application has to draw that buffer on a canvas and it also handles all events.
The normal mode requires a lot less code and it's much faster than the OSR mode but the OSR mode gives the application a much greater control of the browser.
You can compare these two modes with the SimpleBrowser2 and SimpleOSRBrowser demos.
Another CEF configuration option worth mentioning is the use of a multithreaded message loop
.
By default, CEF enables this setting and it will use a background thread to run the browser message loop in order to improve performance. As a result, all CEF events are executed in a CEF thread which is different than the main application thread.
Windows and Linux controls are not thread safe and you should avoid creating, destroying or modifying controls inside CEF events if it's configured to use a multithreaded message loop.
Some demos ignore this because they are oversimplified to keep the code as simple and easy to understand as possible but you should move the GUI handling code to a different procedure and execute it in the main application thread.
If CEF is configured to disable the multithreaded message loop then all CEF events are executed in the main application thread but the browser performance is not as good.
The CEF browsers in MacOS always have to disable the multithreaded message loop.
You can compare the code in the SimpleBrowser2 and ExternalPumpBrowser demos to know all the implementation differences between these two configuration options.
CEF4Delphi comes with many VCL, FMX and LCL components and classes to embed a web browser in all possible CEF configuration settings.
The main class used to simplify the CEF initialization and destruction is TCEFApplication and most of the demos create GlobalCEFApp
as a TCEFApplication instance.
The SubProcess
demos are an exception to this rule to avoid some issues with MS Office and they use TCEFApplicationCore instead.
TCEFApplication creates automatically some CEF handlers only if they are needed. Those handlers are CefApp, CefBrowserProcessHandler, CefRenderProcessHandler, CefResourceBundleHandler and CefLoadHandler.
Read this for more information about this class.
This is the component that puts together all browser procedures, functions, properties and events in one place. It has all you need to create, modify and destroy a web browser.
VCL and LCL applications use TChromium but FireMonkey applications use TFMXChromium. Both components inherit from TChromiumCore which has most of the code but you'll see many references to TChromium in the forum to keep it simple.
TChromiumCore also creates many CEF handlers only if they are needed like CefClient, CefResourceRequestHandler, etc.
Read this for more information about this component.
The TCEFWindowParent component is used in VCL and LCL applications along with a TChromium component to embed a web browser in normal mode.
As commented previously, browsers in normal mode let CEF create some native child controls to show the web contents in them. TCEFWindowParent inherits from TCEFWinControl and it's used as the parent of those child controls. TCEFWindowParent also controls the size of those child controls automatically. See the SimpleBrowser2 demo for more details.
TFMXWindowParent is a FireMonkey component with the same purpose as TCEFWindowParent but due to FMX's code structure it has to inherit from TCommonCustomForm.
TFMXWindowParent is used with a TFMXChromium component and it has to be created at runtime. See the SimpleFMXBrowser demo for more details.
This component can be used by VCL and LCL applications. It has the same purpose as TCEFWindowParent but it has a Chromium property to link it directly to a TChromium component.
TCEFLinkedWindowParent resizes the child controls created by CEF for browsers in normal mode and sets the browser focus using the linked TChromium component.
TCEFWindowParent and TCEFLinkedWindowParent work fine in Windows and you can used any of them but you can't use TCEFWindowParent in Linux or MacOS.
TBufferPanel is used by VCL and LCL applications with browsers in OSR mode to draw the browser contents. TFMXBufferPanel has the same purpose but it's used in FireMonkey applications.
See the SimpleOSRBrowser demo for more details.
TCEFWorkScheduler is used by VCL and LCL applications using CEF browsers with a disabled multithreaded message loop. TFMXWorkScheduler has the same purpose but it's used in FireMonkey applications.
These components handle the GlobalCEFApp.DoMessageLoopWork calls using the delayMs parameter in the GlobalCEFApp.OnScheduleMessagePumpWork event.
VCL and LCL applications must create GlobalCEFWorkScheduler as an instance of TCEFWorkScheduler before creating GlobalCEFApp.
FMX applications must create GlobalFMXWorkScheduler as an instance of TFMXWorkScheduler before creating GlobalCEFApp.
It's also necessary to destroy GlobalCEFApp before destroying GlobalCEFWorkScheduler or GlobalFMXWorkScheduler.
See the ExternalPumpBrowser and FMXExternalPumpBrowser demos for all the implementation details.
TChromiumWindow was created to embed extremely simple web browsers in a slightly easier way than using a TChromium and a TCEFWindowParent pair.
TChromiumWindow can be used in VCL and LCL applications with browsers in normal mode but if you use many TChromium events and procedures you should consider using the other components.
See the SimpleBrowser demo for all the details.
TBrowserWindow is a LCL component that simplifies the creation of multi-platform applications with embedded web browsers in normal mode. TOSRBrowserWindow has the same purpose but it uses browsers in OSR mode.
If you use the same source code to build a Windows, Linux and MacOS application with Lazarus then it's recommended to use these components.
TBrowserWindow and TOSRBrowserWindow were created by Martin_fr (a.k.a. User4martin), one of the Lazarus project administrators.
See all the demos in the Lazarus_any_OS directory for more details.
TCEFServerComponent allows you to create a small HTTP and WebSocket server in VCL, LCL and FMX applications.
It can be used to implement inter-process communication (IPC) between an application and a local host.
See the SimpleServer demo for more details.
TCEFUrlRequestClientComponent allows you to make URL requests unrelated to any browser from a VCL, LCL or FMX application.
See the URLRequest demo for more details.
TCEFSentinel is used as a timer that checks the number of running CEF processes when you close all browsers before shutdown.
This component is only used as a last resort when there's an unresolved shutdown issue in CEF or CEF4Delphi that generates exceptions when the application is closed.
All the components in the Chromium Views Framework
tab allow you to use Views/Aura widgets and layout managers in VCL and LCL applications.
CEF uses this GUI framework internally on Windows, Linux and MacOS to create the browsers.
See the ToolBoxBrowser2 demo and read this document for more details about this framework.
When GlobalCEFApp is configured with the default values CEF enables the multithreaded message loop and it's initialized in a background thread after the GlobalCEFApp.StartMainProcess call.
CEF browsers can only be created when the CEF initialization is complete and this can cause a race condition if an application tries to create a browser when the main application form is shown for the first time.
Most of the demos use a simple TTimer to retry the TChromium.CreateBrowser call after a few milliseconds but it's also possible to use the TCEFApplication.OnGlobalContextInitialized event to send a message to the main form and then create the browsers.
Lazarus applications handle this issue automatically if you use TBrowserWindow or TOSRBrowserWindow.
Chromium requires that all the browsers in your application should be closed correctly before destroying GlobalCEFApp, which is the last step in the project file.
CEF browsers must follow these steps in order to close them correctly :
Each demo has a more detailed destruction sequence in the code comments because each browser configuration can add a few more steps or skip some step but in general, your application should wait until all the TChromium.OnBeforeClose events are executed before closing the application.
Read the code comments in the demo you used as a template for your application to know more details.
FireMonkey is a very powerful framework capable of creating applications for Windows, MacOS, Linux, iOS and Android with the same code but that abstraction layer can make things a little more complicated because CEF needs access to some features at lower API levels.
For example, some Windows demos use a custom class that implements the IFMXApplicationService interface to access Windows messages. Some other demos use a custom WndProc procedure for the same reason. In MacOS the demo uses a custom class that implements the IFMXApplicationService interface to implement CrAppProtocol which is required by Chromium.
If you need to embed a CEF browser with CEF4Delphi in a FireMonkey application you need to add $(FrameworkType) as a conditional define in the project options.
To do that, open the Project
menu and click on Options...
. Then select the Building→Delphi Compiler
option to the left, select All configurations
in the Target
box and type $(FrameworkType) in the Conditional defines
box.
You can also use FMX
without quotes instead of $(FrameworkType) if the conditional define doesn't seem to work in that project.
The CEF4Delphi\demos directory has multiple directories with demos for Delphi and Lazarus :
To test the Windows and Linux demos follow these instructions :
To test the MacOS demos follow the instructions given in the Building the first demo
section for MacOS.
CEF uses several processes and that can make your app difficult to debug in Delphi but in those situations you can use the following tools :
Due to licensing issues and the US patent law, the CEF binaries available at Spotify have the proprietary codecs disabled. If you use those binaries, any website that offers media using H264 won't work.
In case you need to use those codecs, you can build the CEF binaries yourself as described in this forum thread.
Building the CEF binaries requires a very powerful computer. It can take several hours even with an Intel I7 cpu with 16GB of RAM. It's recommended to have 32GB of RAM and to use an SSD drive.
Read the 'Quick Start', 'Branches And Building' and 'Automated Build Setup' articles in the CEF Wiki before building the binaries.
The CEF sources used to build the binaries must have exactly the same CEF version supported by CEF4Delphi at that moment.
Read this forum thread for a shorter guide to build the CEF binaries.
The Adobe Flash PPAPI plugin is no longer supported.
Google dropped support of NPAPI plugins in Chromium 45 released in September 2015. Only the CEF branches older than 2454 support NPAPI plugins for Java, Silverlight or Facebook video.
Browser extensions that don’t require Chrome UI dependencies (toolbar windows, icons, etc) may work. Browser extensions are only supported with Chrome style windows that show some portion of the Chrome UI (like the Chrome toolbar).
CEF4Delphi is just a numeronym and it should be interpreted as CEF for Delphi. It doesn't mean that it's based in CEF4.
If you wish to help in this project you can make a donation by clicking this button :
You can also use Patreon to help this project :
Or sponsor this project on GitHub :
Or sponsor this project on Liberapay :
You can also help by telling your friends about this project, sharing the messages of this project on the social networks, writing articles about this project on your website, making suggestions, reporting issues, etc.
If you shop online you can also help by using these links for your purchases :
Disclosure Statement: This site and BriskBard contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.
This article was updated on April 25th, 2025.