1"use strict";(globalThis.webpackChunkcf_infra_docs=globalThis.webpackChunkcf_infra_docs||[]).push([[16321],{19783(e,n,t){t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var s=t(72250),i=t(74848),r=t(28453);const o={authors:["hmaarrfk","ludmilaklenova"],tags:["ecosystem"]},a="Qt6 status in conda-forge",d={authorsImageUrls:[void 0,void 0]},l=[{value:"A slimmer <code>qt6-main</code>",id:"a-slimmer-qt6-main",level:2},{value:"Qt features (official Qt modules)",id:"qt-features-official-qt-modules",level:2},{value:"Community features (third-party Qt6 libraries)",id:"community-features-third-party-qt6-libraries",level:2},{value:"Python bindings",id:"python-bindings",level:2},{value:"A note on naming",id:"a-note-on-naming",level:2},{value:"What remains",id:"what-remains",level:2},{value:"Thanks",id:"thanks",level:2}];function c(e){const n={a:"a",code:"code",em:"em",h2:"h2",li:"li",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.p,{children:["Qt6 has quietly become a first-class citizen in conda-forge. The recent addition of the Qt Designer Python plugin (",(0,i.jsx)(n.code,{children:"libpyqt6.so"}),") to the ",(0,i.jsx)(n.code,{children:"pyqt6"})," package closed one of the last gaps in the PyQt6 story, but it is a small piece of a much larger, multi-year community effort. This post takes the opportunity to lay out what the whole Qt6 ecosystem now looks like on conda-forge."]}),"\n",(0,i.jsxs)(n.p,{children:["The migration spans more than three years. It started with the first attempts at a 6.x build in ",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/qt-main-feedstock/pull/44",children:"qt-main-feedstock#44"}),' (2022), gathered urgency once Qt 5.15 reached end-of-life in May 2025, and culminated in the "flip" that made Qt6 the default \u2014 the ',(0,i.jsx)(n.code,{children:"qt6"})," branch was merged into ",(0,i.jsx)(n.code,{children:"main"})," in August 2025 (",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/qt-main-feedstock/pull/350",children:"qt-main-feedstock#350"}),"). PyQt6 followed in February 2026 (",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/pyqt-feedstock/pull/162",children:"pyqt-feedstock#162"}),"), and ",(0,i.jsx)(n.code,{children:"qt6-webengine"})," landed in May 2026 (",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/qt-webengine-feedstock/pull/90",children:"qt-webengine-feedstock#90"}),"), removing the last major blocker tracked in ",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/qt-main-feedstock/issues/349",children:"qt-main-feedstock#349"}),"."]}),"\n",(0,i.jsxs)(n.h2,{id:"a-slimmer-qt6-main",children:["A slimmer ",(0,i.jsx)(n.code,{children:"qt6-main"})]}),"\n",(0,i.jsxs)(n.p,{children:["The most important design decision behind this work is invisible to most users: ",(0,i.jsxs)(n.strong,{children:[(0,i.jsx)(n.code,{children:"qt6-main"})," was deliberately slimmed down"]}),". Upstream's ",(0,i.jsx)(n.code,{children:"qt-everywhere"})," source bundles dozens of submodules, and the old approach of shipping them all in one package made the base download enormous and pulled heavy, rarely-needed components (a whole Chromium, GPU/3D stacks, multimedia codecs) into ",(0,i.jsx)(n.em,{children:"every"})," Qt install."]}),"\n",(0,i.jsxs)(n.p,{children:["Instead, the modules were ",(0,i.jsx)(n.strong,{children:"broken out into separate feedstocks"}),", each producing its own ",(0,i.jsx)(n.code,{children:"qt6-*"})," package version-locked to ",(0,i.jsx)(n.code,{children:"qt6-main"}),". The split was driven as much by ",(0,i.jsx)(n.strong,{children:"license hygiene"})," as by size: most of Qt is LGPL, but a few modules (notably Qt Charts, which is GPLv3) would otherwise taint the base package. Keeping ",(0,i.jsx)(n.code,{children:"qt6-main"})," cleanly LGPL is a recurring constraint \u2014 even GPL-encumbered optional dependencies like MySQL were pushed out of the base build (",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/qt-main-feedstock/issues/335",children:"qt-main-feedstock#335"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/qt-main-feedstock/issues/78",children:"qt-main-feedstock#78"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"qt6-main"})," still bundles the Qt ",(0,i.jsx)(n.strong,{children:"Essentials"})," \u2014 Core, GUI, Widgets, Network, Qml/Quick, Test, D-Bus, SQL, OpenGL, PrintSupport \u2014 plus a handful of small, universally-useful modules (SVG, image formats, shader tools, the developer tools like Designer/Linguist/Assistant, translations, Qt5Compat, WebChannel, and WebSockets). Everything heavier is opt-in."]}),"\n",(0,i.jsxs)(n.p,{children:["Because Qt6 promises ABI compatibility across the whole 6.x series, packages only pin ",(0,i.jsx)(n.code,{children:"qt6-main"})," to the major version, which keeps the dependency graph stable across minor releases."]}),"\n",(0,i.jsx)(n.h2,{id:"qt-features-official-qt-modules",children:"Qt features (official Qt modules)"}),"\n",(0,i.jsx)(n.p,{children:"These are modules from The Qt Company / the Qt Project, all released in lockstep (currently 6.11.1). Install only the ones you need:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Package"}),(0,i.jsx)(n.th,{children:"What it provides"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-3d"})}),(0,i.jsx)(n.td,{children:"Qt 3D \u2014 near-realtime simulation and 3D rendering framework"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-charts"})}),(0,i.jsx)(n.td,{children:"2D charts (line, bar, pie, scatter, \u2026) \u2014 shipped separately partly because it is GPLv3"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-datavis3d"})}),(0,i.jsx)(n.td,{children:"3D data visualization (bar, scatter, surface graphs)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-graphs"})}),(0,i.jsx)(n.td,{children:"Newer unified 2D/3D graphing module"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-gtk-platformtheme"})}),(0,i.jsx)(n.td,{children:"GTK3 platform theme plugin for a native GTK look on Linux"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-main"})}),(0,i.jsx)(n.td,{children:"The Qt Essentials base bundle (Core, GUI, Widgets, Network, Qml/Quick, Test, SQL, OpenGL, \u2026) plus SVG, image formats, dev tools, translations, Qt5Compat, WebChannel, WebSockets"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-multimedia"})}),(0,i.jsx)(n.td,{children:"Audio/video playback, recording, and camera access"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-networkauth"})}),(0,i.jsx)(n.td,{children:"OAuth-based authorization to online services"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-positioning"})}),(0,i.jsx)(n.td,{children:"Positioning, satellite info, and area monitoring"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-quick3d"})}),(0,i.jsx)(n.td,{children:"High-level API for 3D content/UIs on top of Qt Quick"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-scxml"})}),(0,i.jsx)(n.td,{children:"State machines from SCXML files"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-sensors"})}),(0,i.jsx)(n.td,{children:"Access to device sensor hardware"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-serialport"})}),(0,i.jsx)(n.td,{children:"Hardware and virtual serial port access"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-wayland"})}),(0,i.jsx)(n.td,{children:"Wayland compositor framework and platform integration (Linux)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-webengine"})}),(0,i.jsx)(n.td,{children:"Chromium-based web content rendering/embedding (the long-awaited piece, added May 2026)"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"community-features-third-party-qt6-libraries",children:"Community features (third-party Qt6 libraries)"}),"\n",(0,i.jsxs)(n.p,{children:["These packages also start with ",(0,i.jsx)(n.code,{children:"qt6"})," but are independent open-source projects built ",(0,i.jsx)(n.em,{children:"for"})," Qt6, not part of an official Qt release:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Package"}),(0,i.jsx)(n.th,{children:"What it is"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-keychain"})}),(0,i.jsxs)(n.td,{children:["Platform-independent API for securely storing passwords (",(0,i.jsx)(n.a,{href:"https://github.com/frankosterfeld/qtkeychain",children:"QtKeychain"}),")"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6-advanced-docking-system"})}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.a,{href:"https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System",children:"Advanced Docking System"})," for dockable UI panels"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qt6molecularnetwork"})}),(0,i.jsx)(n.td,{children:"Graph-visualization widgets used by MetGem"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"python-bindings",children:"Python bindings"}),"\n",(0,i.jsxs)(n.p,{children:["conda-forge ships ",(0,i.jsx)(n.strong,{children:"three"})," complementary ways to use Qt6 from Python:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Package"}),(0,i.jsx)(n.th,{children:"What it is"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"pyside6"})}),(0,i.jsxs)(n.td,{children:["The Qt Company's ",(0,i.jsx)(n.em,{children:"official"}),' "Qt for Python" bindings']})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"pyqt6"})}),(0,i.jsxs)(n.td,{children:["Riverbank Computing's PyQt6 bindings (with ",(0,i.jsx)(n.code,{children:"pyqt6-sip"}),", and add-ons such as ",(0,i.jsx)(n.code,{children:"pyqt6-charts"}),")"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"qtpy"})}),(0,i.jsxs)(n.td,{children:["A compatibility shim that lets a single codebase target PyQt5, PySide2, PyQt6, ",(0,i.jsx)(n.em,{children:"and"})," PySide6"]})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["Shipping both PySide6 and PyQt6, plus ",(0,i.jsx)(n.code,{children:"qtpy"})," to abstract over them (and their Qt5 predecessors), means downstream projects can pick the binding that fits their licensing and feature needs without rewriting their code. For source-editor components, ",(0,i.jsx)(n.code,{children:"qscintilla2"})," is also available."]}),"\n",(0,i.jsxs)(n.p,{children:["The Qt Designer Python plugin that prompted this post is now included in ",(0,i.jsx)(n.code,{children:"pyqt6"})," (",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/pyqt-feedstock/pull/184",children:"pyqt-feedstock#184"}),"), so PyQt6 widgets show up in Designer's widget box."]}),"\n",(0,i.jsx)(n.h2,{id:"a-note-on-naming",children:"A note on naming"}),"\n",(0,i.jsxs)(n.p,{children:["The package names carry history. The original ",(0,i.jsx)(n.code,{children:"qt"})," feedstock now ships a Qt5 metapackage (",(0,i.jsx)(n.code,{children:"qt"})," \u2192 ",(0,i.jsx)(n.code,{children:"qt-main"})," 5.15); ",(0,i.jsx)(n.code,{children:"qt-main-feedstock"})," builds ",(0,i.jsx)(n.code,{children:"qt-main"})," (Qt5) on its ",(0,i.jsx)(n.code,{children:"qt5"})," branch and ",(0,i.jsx)(n.code,{children:"qt6-main"})," (Qt6) on ",(0,i.jsx)(n.code,{children:"main"}),". Encoding the major version into the package name (",(0,i.jsx)(n.code,{children:"qt6-main"}),") is what lets Qt5 and Qt6 coexist across the ecosystem during the long transition. See ",(0,i.jsx)(n.a,{href:"https://github.com/conda-forge/qt-main-feedstock/issues/349",children:"qt-main-feedstock#349"})," for the wrap-up plan."]}),"\n",(0,i.jsx)(n.h2,{id:"what-remains",children:"What remains"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"PyQt6 WebEngine"})," \u2014 ",(0,i.jsx)(n.code,{children:"qt6-webengine"}
1)," now exists, but the PyQt6 WebEngine ",(0,i.jsx)(n.em,{children:"bindings"})," are not yet packaged. PySide6 includes WebEngine support today, so projects needing web content from Python can use PySide6 (or ",(0,i.jsx)(n.code,{children:"qt6-webengine"})," directly)."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"thanks",children:"Thanks"}),"\n",(0,i.jsxs)(n.p,{children:["Thanks to everyone who has worked on the Qt6 transition over the years: ",(0,i.jsx)(n.a,{href:"https://github.com/hmaarrfk",children:"@hmaarrfk"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/jschueller",children:"@jschueller"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/h-vetinari",children:"@h-vetinari"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/traversaro",children:"@traversaro"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/andfoy",children:"@andfoy"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/Tobias-Fischer",children:"@Tobias-Fischer"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/JarrettSJohnson",children:"@JarrettSJohnson"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/ccordoba12",children:"@ccordoba12"}),", ",(0,i.jsx)(n.a,{href:"https://github.com/ludmilaklenova",children:"@ludmilaklenova"}),", and many others."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},28453(e,n,t){t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}},72250(e){e.exports=JSON.parse('{"permalink":"/blog/2026/07/01/qt6-status-in-conda-forge","editUrl":"https://github.com/conda-forge/conda-forge.github.io/tree/refs/heads/main/blog/2026-07-01-qt6-status-in-conda-forge.md","source":"@site/blog/2026-07-01-qt6-status-in-conda-forge.md","title":"Qt6 status in conda-forge","description":"Qt6 has quietly become a first-class citizen in conda-forge. The recent addition of the Qt Designer Python plugin (libpyqt6.so) to the pyqt6 package closed one of the last gaps in the PyQt6 story, but it is a small piece of a much larger, multi-year community effort. This post takes the opportunity to lay out what the whole Qt6 ecosystem now looks like on conda-forge.","date":"2026-07-01T00:00:00.000Z","tags":[{"inline":true,"label":"ecosystem","permalink":"/blog/tags/ecosystem"}],"readingTime":5.13,"hasTruncateMarker":true,"authors":[{"name":"Mark Harfouche","title":"Member of conda-forge/core","url":"https://github.com/hmaarrfk","imageURL":"https://github.com/hmaarrfk.png","key":"hmaarrfk","page":null},{"name":"Lioudmila Klenov","title":"Contributor","url":"https://github.com/ludmilaklenova","imageURL":"https://github.com/ludmilaklenova.png","key":"ludmilaklenova","page":null}],"frontMatter":{"authors":["hmaarrfk","ludmilaklenova"],"tags":["ecosystem"]},"unlisted":false,"prevItem":{"title":"Python 3.15.0rc1 on conda-forge, a leaner libpython, and a more unixy Windows layout","permalink":"/blog/2026/09/03/python-315"},"nextItem":{"title":"New large runners available for GitHub Actions","permalink":"/blog/2026/06/17/large-runners-gha"}}')}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.