WebKit is an open-source Web browser engine. It’s a framework in macOS and iOS, and used by many first party and third party applications including Safari, Mail, Notes, Books, News, and App Store.
The WebKit codebase is mostly written in C++ with bits of C and assembly, primarily in JavaScriptCore, and some Objective-C to integrate with Cocoa platforms.
It primarily consists of the following components, each inside its own directory in Source:
There are many ways to get involved and contribute to the WebKit Project. Filing a new bug, fixing a bug, or adding a new feature.
There are three different kinds of contributors in the WebKit project.
See Commit and Review Policy for more details on how to become a committer or a reviewer.
Before getting in touch with WebKit developers using any of the avenues below, make sure that you have checked our page on how to ask questions about WebKit.
You can find WebKit developers, testers, and other interested parties on the #WebKit Slack workspace. Join the WebKit slack, and stay in touch.
bugs.webkit.org hosted is the primary bug tracking tool we use. When making a code change, we post a code change (patch) on this website.
To file a new WebKit bug, see reporting bugs.
To edit an existing bug, you may need editbug-bits.
We also use bugs.webkit.org to upload & review code changes to WebKit. You can post a code change with Tools/Scripts/webkit-patch upload
. Note that the webkit-patch
script only looks for changes below current directory, so generally you should change the current directory to the top-level directory of a WebKit first.
When a patch is posted on bugs.webkit.org requesting a formal code review (r? flag is set), The Early Warning System (a.k.a. EWS) will automatically build and run tests against your code change. This allows contributors to find build or test failures before committing code changes to the WebKit’s primary Subversion repository.
Once a patch is approved by a reviewer (r+ flag is set), then the patch can be either committed directly into the Subversion repository by a WebKit committer, who has write access to the Subversion repository, or via the commit queue which can be requested by setting cq? flag and approved by any WebKit committer by setting cq+.
The Subversion commit message should be created by Tools/Scripts/commit-log-editor
based on the change log entries. Tools/Scripts/webkit-patch land
does this automatically.
Security bugs have their own components in bugs.webkit.org. We’re also working on a new policy to delay publishing tests for security fixes until after the fixes have been widely deployed.
Do not post a patch or describe a security bug in a bug that is not in security component of bugs.webkit.org.
See Getting the Code
For convenience, you can add Tools/Scripts/
to your path as follows in ~/.zshrc
like so:
export PATH=$PATH:/Volumes/Data/webkit/Tools/Scripts/
where /Volumes/Data/webkit
is the path to a WebKit checkout.
This will allow you to run various tools you by name instead of typing the full path of the script.
There is a script to update a WebKit checkout: Tools/Scripts/update-webkit
. This script will automatically merge change logs mentioned below.
If you see mysterious build failures or if you’ve switched to a new version of macOS or Xcode, delete the WebKitBuild
directory. make clean
may not delete all the relevant files, and building after doing that without deleting the WebKitBuild
directory may result in mysterious build or dyld errors.
To build Address Sanitizer or ASan builds to analyze security bugs, run Tools/Scripts/set-webkit-configuration --asan --release
. This will enable ASan build. If want to attach a debugger, you can also specify --debug
instead of --release
. Once you don’t need to build or run ASan anymore, you can specify --no-asan
in place of --asan
to disable ASan. Note that this configuration is saved by creating a file called Asan in the WebKitBuild directory, so if you are trying to do a clean Asan build by deleting the build directory you need to rerun this command.
You can also use Xcode to build & debug WebKit. Open WebKit.xcworkspace
at the top level directory.
In order to make Xcode use build files built by make
command above, go to File > Workspace Settings... > Advanced... > Custom > Relative to Workspace and adjust the relative paths of Products and Intermediates to point to WebKitBuild
directory. Note that debugging WebCore code typically requires attaching to the relevant WebContent process, not the application process, which is mostly running code in Source/WebKit/UIProcess. Depending on what you’re debugging, you’d have to attach & debug different processes in the coalition.
You may find it useful to use the debug helpers under Tools/lldb/lldb_webkit.py
. This can be added to ~/.lldbinit
for automatic loading into LLDB on launch by adding the line command script import {Path to WebKit}/Tools/lldb/lldb_webkit.py
. For more details, see the Wiki article on lldb formatters.
When debugging a debug build in LLDB, there are also a few functions that can be called on objects that will dump debugging info.
WebKit is really big on test driven development, we have many types of tests.
Tools/Scripts/run-javascriptcore-tests
to run these tests.Tools/Scripts/run-webkit-tests
to run these. Pass -1
to run tests using WebKitLegacy (a.k.a. WebKit1). WebKitTestRunner is used to run these tests for WebKit2, and DumpRenderTree is used to these tests for WebKit1. There are a few styles of layout tests but all of them have a test file and expected result (ends with -expected.txt), and the test passes if the test file’s output matches that of the expected result.Tools/Scripts/run-api-tests
to run these tests. Because these API tests are sequentially, it’s preferable to write layout tests when possible.Tools/Scripts/run-bindings-tests
to run these tests.Tools/Scripts/test-webkitpy
to run these tests.Tools/Scripts/test-webkitperl
to run these tests.The WebKit project has a “no performance regression” policy. We maintain the performance of the following of the benchmarks and are located under PerformanceTests. If your patch regresses one of these benchmarks even slightly (less than 1%), it will get reverted.
The following are benchmarks maintained by Apple‘s WebKit team but not available to other open source contributors since Apple doesn’t have the right to redistribute the content. If your WebKit patch regresses one of these tests, your patch may still get reverted.
WebKit has a rigorous code contribution process and policy in place to maintain the quality of code.
Code you write must follow WebKit’s coding style guideline. You can run Tools/Scripts/check-webkit-style
to check whether your code follows the coding guidelines or not (it can report false positives or false negatives). If you use Tools/Scripts/webkit-patch upload
to upload your patch, it automatically runs the style checker against the code you changed so there is no need to run check-webkit-style
separately.
Some older parts of the codebase do not follow these guidelines. If you are modifying such code, it is generally best to clean it up to comply with the current guidelines.
Tools/Scripts/webkit-patch
provides a lot of utility functions like applying the latest patch on bugs.webkit.org (apply-from-bug
) and uploading a patch (upload --git-commit=<commit hash>
) to a bugs.webkit.org bug. Use --all-commands
to the list of all commands this tool supports.
Much of the code we inherited from KHTML is licensed under LGPL. New code contributed to WebKit will use the two clause BSD license. When contributing new code, update the copyright date. When moving the existing code, you need to include the original copyright notice for the moved code and you should also not change the license, which may be BSD or LGPL depending on a file, without the permission of the copyright holders.
Once you have made a code change, you need to run the aforementioned tests (layout tests, API tests, etc...) to make sure your code change doesn’t break existing functionality. These days, uploading a patch on bugs.webkit.org triggers the Early Warning System (a.k.a. EWS)
For any bug fix or a feature addition, there should be a new test demonstrating the behavior change caused by the code change. If no such test can be written in a reasonable manner (e.g. the fix for a hard-to-reproduce race condition), then the reason writing a tests is impractical should be explained in the accompanying change log.
Any patch which introduces new test failures or performance regressions may be reverted. It’s in your interest to wait for the Early Warning System to fully build and test your patch on all relevant platforms.
ChangeLogs are simple text files which provide historical documentation for all changes to the WebKit project. All patches require an entry to the ChangeLog.
The first line contains the date, your full name, and your email address. Use this to write up a brief summary of the changes you’ve made. Don’t worry about the “Reviewed by NOBODY (OOPS!)” line, the person landing your patch will fill this in. There is one ChangeLog per top-level directory. If you changed code and tests you will need to edit at least two ChangeLogs. Tools/Scripts/prepare-ChangeLog
script will create stub entries for ChangeLog files based on code changes you made in your Git or Subversion checkouts.
You should edit these stubs to describe your change, including the full URL to the bug (example entry, note that you can use --bug
flag). (You should set EMAIL_ADDRESS
and CHANGE_LOG_NAME
in your environment if you will be running this script frequently.) A typical change log entry before being submitted to bugs.webkit.org looks like this:
2012-10-04 Enrica Casucci <e•••••@apple.com> Font::glyphDataAndPageForCharacter doesn't account for text orientation when using systemFallback on a cold cache. https://bugs.webkit.org/show_bug.cgi?id=98452. Reviewed by NOBODY (OOPS!). The text orientation was considered only when there is a cache hit. This change moves the logic to handle text orientation to a separate inline function that is called also when the glyph is added to the cache. Test: fast/text/vertical-rl-rtl-linebreak.html * platform/graphics/FontFastPath.cpp: (WebCore::applyTextOrientationForCharacter): Added. (WebCore::Font::glyphDataAndPageForCharacter): Modified to use the new function in both cases of cold and warm cache.
The “No new tests. (OOPS!)” line appears if prepare-ChangeLog
did not detect the addition of new tests. If your patch does not require test cases (or test cases are not possible), remove this line and explain why you didn’t write tests. Otherwise all changes require test cases which should be mentioned in the ChangeLog.
Apple’s macOS, iOS, watchOS, and tvOS ports use Xcode and the rest use CMake to build WebKit. There is an ongoing effort to make Apple's ports also use CMake.
In order to reduce the compilation time, which used to take 40+ minutes on the fully loaded 2018 15“ MacBook Pro, we bundle up multiple C++ translation units (.cpp files) and compile them as a single translation unit. We call this mechanism Unified Sources or Unified Builds.
Unified sources are generated under WebKitBuild/X/DerivedSources
where X is the name of build configuration such as Debug
and Release-iphonesimulator
. For example, WebKitBuild/Debug/DerivedSources/WebCore/unified-sources/UnifiedSource116.cpp
may look like this:
#include "dom/Document.cpp" #include "dom/DocumentEventQueue.cpp" #include "dom/DocumentFragment.cpp" #include "dom/DocumentMarkerController.cpp" #include "dom/DocumentParser.cpp" #include "dom/DocumentSharedObjectPool.cpp" #include "dom/DocumentStorageAccess.cpp" #include "dom/DocumentType.cpp"
To add a new header file or a translation unit (e.g. .cpp
, .m
, or .mm
), open WebKit.xcworkspace and add respective files in each directory.
Make sure to uncheck the target membership so that it’s not compiled as a part of the framework in xcodebuild. Instead, add the same file in Sources.txt file that exists in each subdirectory of Source. e.g. Source/WebCore/Sources.txt for WebCore. This will ensure the newly added file is compiled as a part of unified sources. When a header file in WTF is used in WebCore, or a header file in WebCore is used in WebKit or WebKitLegacy, we need to export the file to those projects. To do that, turn on the target membership in respective framework as set the membership to “Private” as seen below. This will ensure the relevant header file is exported from WTF / WebCore to other downstream projects like WebKitLegacy.