'use client' /* eslint-disable @next/next/no-img-element */ import { Fragment, useEffect } from 'react' import { FaDiscord, FaGithub } from 'react-icons/fa' import HuggingFaceSVG from '@/assets/icons/huggingface.svg' import CuteRobotBgMountainPNG from '@/assets/landing/cute-robot-bg-mountain.png' import { Button } from '@/components/ui/button' import CodeSVG from '@/assets/icons/code.svg' import { IoMdPeople } from 'react-icons/io' import CuteBuildingRobotPNG from '@/assets/landing/cute-building-robot.png' import CuteRobotFlyingPNG from '@/assets/landing/cute-robot-flying.png' import ShareSVG from '@/assets/icons/share-android.svg' import RobotSVG from '@/assets/icons/robot.svg' import LogoJanSVG from '@/assets/icons/logo-jan.svg' import AppJanPNG from '@/assets/landing/app-jan.png' import TweetSection from '@/components/TweetSection' import FavoriteModels from '@/components/FavoriteModels' import { DropdownButton } from '@/components/ui/dropdown-button' import { useData } from 'nextra/data' import { useDiscordWidget } from '@/hooks/useDiscordWidget' import { formatCompactNumber, totalDownload } from '@/utils/format' const Home = () => { const { lastVersion, lastRelease, stars, release } = useData() const { data: discordWidget } = useDiscordWidget() useEffect(() => { const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px', } const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const element = entry.target as HTMLElement const delay = element.dataset.delay || '0' setTimeout(() => { element.classList.add('animate-in-view') }, parseInt(delay)) observer.unobserve(element) } }) }, observerOptions) // Observe all scroll-triggered animation elements const animatedElements = document.querySelectorAll( '.animate-on-scroll, .animate-on-scroll-left, .animate-on-scroll-right, .animate-on-scroll-scale, .animate-slide-up' ) animatedElements.forEach((element) => { observer.observe(element) }) // Simple parallax effect for robot images const handleScroll = () => { const parallaxElements = document.querySelectorAll('.parallax-element') parallaxElements.forEach((el) => { const element = el as HTMLElement const rect = element.getBoundingClientRect() // Only apply parallax when element is visible if (rect.top < window.innerHeight && rect.bottom > 0) { const speed = parseFloat(element.getAttribute('data-speed') || '0.3') // Simple calculation: how far the element has moved into/through viewport const progress = Math.min( 1, Math.max(0, (window.innerHeight - rect.top) / window.innerHeight) ) // Move from 0 to -40px based on progress const yPos = Math.round(progress * -100 * speed) element.style.transform = `translateY(${yPos}px)` } }) } window.addEventListener('scroll', handleScroll) // Cleanup function return () => { observer.disconnect() window.removeEventListener('scroll', handleScroll) } }, []) return ( {/* Hero */}
NEW {lastVersion} is now live on GitHub. Check it out!
Logo Jan

Ask Jan

Jan is the open-source ChatGPT replacement.

Jan App Interface
Jan App Interface
{/* Statistic and social */}

Over 4 million downloads

{/* Social tech */}

Towards Open Superintelligence

Jan takes the best of open source AI and packages it into an easy-to-use product.

{/* Favorite Models Section */} {/* Developer Community */}

Built in Public

Our core team believes that AI should be open,{' '}
and Jan is built in public.

Develop

Submit PRs for UI, tooling, or edge optimizations.

Train

Add evals, safety tests, or training recipes.

{/* Call to action */}

Ask Jan,

get things done

+{totalDownload(release)} downloads, Free & Open source
{/* */} {/* */} {/* */} {/* */} {/* */} {/* */} {/* */} {/* */} {/* */}
) } export default Home