- We can support you to self-host Nx Cloud within your own
- infrastructure or, depending on your needs, run Nx Cloud on
- managed hosts within our cloud.
-
@@ -100,7 +120,7 @@ export function Security(): JSX.Element {
aria-hidden="true"
>
-
-
-
- Solve your CI
-
-
-
- Monorepos help you scale your people but they can also make CI a
- challenge. Nx Enterprise solves it by providing efficient, fast and
- reliable CI that can handle workflows of any size.
-
- {/*FEATURES CONTAINER*/}
-
- {items.map((item, i) => (
- p:text-lg]', item.className)}
- icon={item.icon}
- url={item.url}
- />
- ))}
-
-
- {/*TEXT*/}
-
-
-
-
-
-
-
-
-
-
-
- Both faster and cheaper
-
-
- Current CI providers aren’t made for monorepos. They’re
- low-level and static in their configuration. The combination
- of Nx Agents and Nx Replay lets you reuse computation from
- other runs and utilizes the allocated VMs in the most optimal
- way.
-
-
-
-
-
-
-
-
-
- Solving E2E tests
-
-
- Atomizer splits large e2e projects into fine-grained test
- runs, enabling more efficient distribution and dramatically
- reducing CI times. It also identifies flaky e2e tests at the
- file level and re-runs those specific tests.
-
-
-
-
-
-
-
-
-
- What, not how
-
-
- Nx Enterprise simplifies CI configuration, emphasizing which
- tasks to execute over how with no need to tweak your CI
- scripts as your monorepo evolves. This simplified
- configuration cuts down on CI maintenance and increases
- stability.
-
-
-
-
-
-
-
-
-
- Nx Powerpack included
-
-
- A suite of paid extensions for the Nx CLI specifically
- designed for enterprises, built and supported by the Nx core
- team.{' '}
-
- Learn more about Nx Powerpack →
-
-
-
-
-
-
-
-
- );
-}
-
-const Caching = () => {
- const variants = {
- hidden: {
- opacity: 0,
- transition: {
- when: 'afterChildren',
- },
- },
- visible: {
- opacity: 1,
- },
- };
- const items = [
- {
- cache: 'remote',
- target: 'build',
- project: 'website',
- },
- {
- cache: 'remote',
- target: 'test',
- project: 'express',
- },
- {
- cache: 'remote',
- target: 'build',
- project: 'eslint',
- },
- {
- cache: 'remote',
- target: 'lint',
- project: 'autoloan',
- },
- {
- cache: 'remote',
- target: 'test',
- project: 'website',
- },
- {
- cache: 'remote',
- target: 'lint',
- project: 'website',
- },
- {
- cache: 'remote',
- target: 'build-base',
- project: 'express',
- },
- {
- cache: 'remote',
- target: 'build',
- project: 'express',
- },
- {
- cache: 'remote',
- target: 'lint',
- project: 'express',
- },
- {
- cache: 'remote',
- target: 'test',
- project: 'autoloan',
- },
- ];
- return (
-
-
-
-
-
-
- tasks replayed instantly with cache
-
-
- {items.map((i, idx) => (
-
-
-
-
- {i.cache}
-
-
-
- {i.project}:{i.target}
-
-
< 1s
-
- ))}
-
-
- );
-};
-
-const Atomizer = () => {
- const variants = {
- hidden: {
- opacity: 0,
- transition: {
- when: 'afterChildren',
- },
- },
- visible: {
- opacity: 1,
- },
- };
- const itemVariants = {
- visible: (i: number) => ({
- opacity: 1,
- x: 0,
- transition: {
- delay: i * 0.2,
- duration: 0.275,
- ease: 'easeOut',
- when: 'beforeChildren',
- staggerChildren: 0.3,
- },
- }),
- hidden: {
- opacity: 0,
- x: -100,
- transition: {
- when: 'afterChildren',
- },
- },
- };
- const uiDialogsTests = ['e2e-ui-cdk:e2e', 'e2e-ui-layout:e2e'];
- const loansTests = [
- 'loans-front-store:e2e',
- 'loans-loans:e2e',
- 'loans-credit-card:e2e',
- 'loans-workflows:e2e',
- 'loans-mortgage:e2e',
- 'loans-submission:e2e',
- ];
- const DefaultConnector = () => (
- <>
-
-
- >
- );
- const BottomConnector = () => (
- <>
-
-
- >
- );
-
- return (
-
-
- Running
-
- nx affected --targets=e2e
-
-
-
-
-
-
-
- In progress
-
-
-
-
- E2E {'>'} CI
-
-
- {uiDialogsTests.map((i, idx) => (
-
- {uiDialogsTests.length === idx + 1 ? (
-
- ) : (
-
- )}
-
-
-
{i}
-
- ))}
-
-
-
-
- miss
-
-
-
- website:e2e
-
-
- flaky
-
-
- 1 retry
-
-
-
-
-
-
-
- In progress
-
-
-
-
- loans {'>'} e2e
-
-
- {loansTests.map((i, idx) => (
-
- {loansTests.length === idx + 1 ? (
-
- ) : (
-
- )}
-
-
-
{i}
-
- ))}
-
-
- );
-};
-
-const TaskDistribution = () => {
- const variants = {
- hidden: {
- opacity: 0,
- transition: {
- when: 'afterChildren',
- },
- },
- visible: {
- opacity: 1,
- },
- };
- const itemVariants = {
- visible: (i: number) => ({
- opacity: 1,
- x: 0,
- transition: {
- delay: i * 0.2,
- duration: 0.275,
- ease: 'easeOut',
- when: 'beforeChildren',
- staggerChildren: 0.3,
- },
- }),
- hidden: {
- opacity: 0,
- x: -100,
- transition: {
- when: 'afterChildren',
- },
- },
- };
- const agent1Items = ['website:build-base', 'website:build'];
- const agent2Items = ['docs:lint', 'express:test', 'website:lint'];
- const agent3Items = ['graph-client:build', 'plugin:test'];
- const nxReplayItems = [
- 'graph-client:lint',
- 'plugin:lint',
- 'website:test',
- 'vite:test',
- 'vite:build',
- ];
-
- const notStartedTasks = ['js:build', 'js:lint'];
- return (
-
-
-
-
- Main Workflow
-
-
-
- nx affected --target=build,lint,test
-
-
-
- {notStartedTasks.map((i, idx) => (
-
- {i}
-
- ))}
-
-
-
-
-
- Nx Agents
-
-
-
-
-
-
- Agent 1
-
{agent1Items.length}
-
-
-
- {agent1Items.map((i, idx) => (
-
- {i}
-
- ))}
-
-
-
-
-
-
- Agent 2
-
{agent2Items.length}
-
-
-
- {agent2Items.map((i, idx) => (
-
- {i}
-
- ))}
-
-
-
-
-
-
- Agent 3
-
{agent3Items.length}
-
-
-
- {agent3Items.map((i, idx) => (
-
- {i}
-
- ))}
-
-
-
-
-
-
- Nx Replay
-
-
- {nxReplayItems.map((i, idx) => (
-
- {i}
-
- ))}
-
-
-
-
- );
-};
-
-const IncreasedVisibility = () => {
- const variants = {
- hidden: {
- opacity: 0,
- transition: {
- when: 'afterChildren',
- },
- },
- visible: {
- opacity: 1,
- },
- };
-
- return (
-
-
- {/*STATUS*/}
-
-
-
- Failed
-
- with code: 1
-
-
- {/*COMPARE & FLAKY*/}
- {/*
-
-
-
*/}
-
-
-
-
- Attempt 1
-
-
- Attempt 2
-
-
-
-
- Feb 23, 2024 08:57:49 - 08:57:54 (4s)
-
-
-
-
- nx run nx-dev:build
-
-
-
-
-
-
-
-
- {`nx run nx-dev:sitemap ✨ [next-sitemap]
-Loading next-sitemap config:file:///home/workflows/workspace/nx-dev/nx-dev/next-sitemap.config.js
-❌ [next-sitemap] Unable to find export-maker.
- Make sure to build the project using "next build" command
- node:internal/process/promises:289
- triggerUncaughtException(err, true /* fromPromise */); ^
- [Error:ENOENT: no such file or directory, stat '/home/workflows/workspace/dist/nx-dev/nx-dev/.next/export-marker.json']
- errno: -2, code: 'ENOENT', syscall: 'stat', path: '/home/workflows/workspace/dist/nx-dev/nx-dev/.next/export-marker.json'
-Node.js v20.9.0 Warning: command "pnpm next-sitemap --config
-./nx-dev/nx-dev/next-sitemap.config.js" exited with non-zero status code`}
-
-
-
-
- );
-};
-
-export function Counter({
- value,
- duration = 2,
-}: {
- value: number;
- duration?: number;
-}) {
- const count = useMotionValue(0);
- const rounded = useTransform(count, Math.round);
-
- useEffect(() => {
- const animation = animate(count, value, {
- type: 'tween',
- ease: 'easeOut',
- duration,
- });
-
- return animation.stop;
- }, []);
-
- return
{rounded};
-}
-
-const items = [
- {
- title: 'Nx Agents: seamless task distribution',
- header:
,
- className: 'md:col-span-2',
- icon:
,
- url: '/ci/features/distribute-task-execution',
- },
- {
- title: 'Nx Replay: secure computation cache',
- header:
,
- className: 'md:col-span-1',
- icon:
,
- url: '/ci/features/remote-cache',
- },
- {
- title: 'Increased visibility',
- header:
,
- className: 'md:col-span-1',
- icon:
,
- },
- {
- title: 'Atomizer: task splitting & flaky rerun',
- description: null,
- header:
,
- className: 'md:col-span-2',
- icon:
,
- url: '/ci/features/split-e2e-tasks',
- },
-];
diff --git a/nx-dev/ui-enterprise/src/lib/testimonial-carousel.tsx b/nx-dev/ui-enterprise/src/lib/testimonial-carousel.tsx
new file mode 100644
index 00000000000000..df231aa7a54515
--- /dev/null
+++ b/nx-dev/ui-enterprise/src/lib/testimonial-carousel.tsx
@@ -0,0 +1,196 @@
+import { ReactElement, ReactNode, useRef, useState } from 'react';
+import {
+ CarouselHandle,
+ CarouselRoot,
+ CarouselSlide,
+ CarouselViewport,
+} from './carousel';
+import { PayfitIcon, UkgIcon } from '@nx/nx-dev/ui-icons';
+
+export function Carousel({
+ items,
+}: {
+ items: { element: ReactNode; innerButtonElement: ReactNode }[];
+}): ReactElement {
+ const carouselRef = useRef
(null);
+ const iterableItems = items.map((item, index) => ({
+ ...item,
+ id: crypto.randomUUID(),
+ }));
+ const [currentIndex, setCurrentIndex] = useState(0);
+ const handleSlideChange = (index: number) => setCurrentIndex(index);
+
+ return (
+
+ {/* Main carousel section */}
+
+
+ {iterableItems.map((item, index) => (
+ {item.element}
+ ))}
+
+
+ {/* Custom line-style indicators */}
+
+ {iterableItems.map((_, index) => (
+
+ ))}
+
+
+
+ {/* Partner logos section - now linked to carousel items */}
+
+ {iterableItems.map((item, index) => (
+
+ ))}
+
+
+ );
+}
+
+export function TestimonialCarousel(): ReactElement {
+ return (
+
+
+
+
+
+
+
+
+
+
+ “The number of hours we spent trying to manage CI
+ before, trying to load balance in CircleCI, the
+ number of agents that we run ourselves by hand and
+ try to distribute ourselves manually - it was
+ painful, we’d spend hours and days trying to do
+ that.{' '}
+
+ With Nx Cloud we don’t need to think about that,
+ here is my task, deal with it and make it fast
+
+ .”
+
+
+
+
+
+
+ Nicolas Beaussart
+
+
+ Staff Platform Engineer, Payfit
+
+
+
+
+
+
+
+
+ ),
+ // innerButtonElement: (
+ //
+ // ),
+ innerButtonElement: (
+ Increase speed
+ ),
+ },
+ {
+ element: (
+
+
+
+
+
+
+
+
+ “I really like the Nx check-ins - Nx people are very
+ well prepared for how to help their team grow and
+ scale and to help us spot some of our challenges. I
+ can’t see a future where we don’t have Nx.”
+
+
+
+
+
+
Sid Govindaraju
+
Engineering Manager, UKG
+
+
+
+
+
+
+
+
+
+ ),
+ // innerButtonElement: (
+ //
+ // ),
+ innerButtonElement: (
+ Proactive partnership
+ ),
+ },
+ ]}
+ />
+
+
+ );
+}
diff --git a/nx-dev/ui-enterprise/src/lib/trusted-by.tsx b/nx-dev/ui-enterprise/src/lib/trusted-by.tsx
deleted file mode 100644
index c8c2b95600d632..00000000000000
--- a/nx-dev/ui-enterprise/src/lib/trusted-by.tsx
+++ /dev/null
@@ -1,220 +0,0 @@
-import {
- AwsIcon,
- BillColoredIcon,
- CapitalOneIcon,
- CaterpillarIcon,
- CiscoIcon,
- FicoIcon,
- HiltonIcon,
- ManIcon,
- ReactQueryIcon,
- RedwoodJsIcon,
- RoyalBankOfCanadaColoredIcon,
- SevenElevenColoredIcon,
- ShopifyIcon,
- StorybookIcon,
- VmwareIcon,
-} from '@nx/nx-dev/ui-icons';
-import { motion } from 'framer-motion';
-
-export function TrustedBy(): JSX.Element {
- const variants = {
- hidden: {
- opacity: 0,
- transition: {
- when: 'afterChildren',
- },
- },
- visible: (i: number) => ({
- opacity: 1,
- transition: {
- delay: i || 0,
- },
- }),
- };
- const itemVariants = {
- visible: (i: number) => ({
- opacity: 1,
- y: 0,
- transition: {
- delay: i * 0.25,
- duration: 0.65,
- ease: 'easeOut',
- when: 'beforeChildren',
- staggerChildren: 0.3,
- },
- }),
- hidden: {
- opacity: 0,
- y: 4,
- transition: {
- when: 'afterChildren',
- },
- },
- };
-
- return (
-
- );
-}
diff --git a/nx-dev/ui-enterprise/src/lib/vmware-testimonial.tsx b/nx-dev/ui-enterprise/src/lib/vmware-testimonial.tsx
new file mode 100644
index 00000000000000..94f7ea9bc004b5
--- /dev/null
+++ b/nx-dev/ui-enterprise/src/lib/vmware-testimonial.tsx
@@ -0,0 +1,48 @@
+import { ReactElement } from 'react';
+import { VmwareIcon } from '@nx/nx-dev/ui-icons';
+import { ButtonLink, SectionHeading } from '@nx/nx-dev/ui-common';
+import { ArrowDownTrayIcon } from '@heroicons/react/24/outline';
+
+export function VmwareTestimonial(): ReactElement {
+ return (
+
+ );
+}
diff --git a/nx-dev/ui-icons/src/lib/customers/hetzner-cloud.tsx b/nx-dev/ui-icons/src/lib/customers/hetzner-cloud.tsx
index 8f1eea7d866030..3652fdb0ad65ea 100644
--- a/nx-dev/ui-icons/src/lib/customers/hetzner-cloud.tsx
+++ b/nx-dev/ui-icons/src/lib/customers/hetzner-cloud.tsx
@@ -1,7 +1,9 @@
import { FC, SVGProps } from 'react';
+/**
+ * Use `#D50C2D` for a colored version.
+ */
export const HetznerCloudIcon: FC