npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@lucodifier/dashund-core

v1.0.0

Published

🐕 Framework React ultra-leve com SEO perfeito, sem SSR

Readme

🐕 Dashund

O doguinho que corre atrás do SEO que o React esqueceu.

Framework React ultra-leve (~5kb) com SEO perfeito, sem necessidade de SSR (Server-Side Rendering).

License: MIT npm version


✨ Por que Dashund?

Cansado da complexidade do Next.js só para ter SEO? O Dashund resolve isso de forma simples:

  • Zero SSR - Sem servidor Node.js necessário
  • SEO Perfeito - Meta tags, Open Graph, Twitter Cards e JSON-LD automáticos
  • Ultra Leve - ~5kb gzipped (16x menor que Next.js)
  • Static Generation - HTML pré-renderizado para cada rota
  • SPA Navigation - Navegação instantânea sem reload
  • Dynamic Routes - Suporte completo a /blog/:id e parâmetros
  • CLI Integrado - Gerador de projetos como create-react-app
  • Deploy Simples - Funciona em qualquer CDN (Netlify, Vercel, Cloudflare Pages)

📦 Instalação

Criar Novo Projeto (Recomendado)

npx dashund create meu-projeto
cd meu-projeto
npm run dev

Instalação Manual

npm install @dashund/core react react-dom

🚀 Quick Start

Usando o CLI

# Criar projeto
dashund create meu-blog

# Entrar no diretório
cd meu-blog

# Iniciar desenvolvimento
npm run dev

# Build para produção
npm run build

Uso Programático

import Dashund from '@dashund/core';
import Home from './pages/Home';
import Blog from './pages/Blog';
import BlogPost from './pages/BlogPost';

const app = new Dashund({
  baseUrl: 'https://meusite.com',
  scrollToTop: true
});

// Rotas estáticas
app.route('/', Home, {
  title: 'Home - Meu Site',
  description: 'Site incrível com SEO perfeito',
  keywords: 'react, seo, framework'
});

// Rotas dinâmicas
app.route('/blog/:id', BlogPost, {
  title: 'Blog Post',
  description: 'Leia nossos artigos'
});

// Inicializar app
app.init('root');

📁 Templates Disponíveis

Blog Template (Padrão)

Blog completo com Tailwind CSS, páginas pré-configuradas e SEO otimizado.

dashund create meu-blog --template blog

Inclui:

  • ✅ Home Page com hero e features
  • ✅ Blog Listing com cards
  • ✅ Blog Post com rotas dinâmicas (/blog/:id)
  • ✅ About Page
  • ✅ Tailwind CSS configurado
  • ✅ Componentes reutilizáveis (Header, Footer, Layout, Card)
  • ✅ SEO completo e automático

Estrutura do Projeto:

meu-blog/
├── src/
│   ├── pages/
│   │   ├── Home.jsx
│   │   ├── Blog.jsx
│   │   ├── BlogPost.jsx
│   │   └── About.jsx
│   ├── components/
│   │   ├── Layout.jsx
│   │   ├── Header.jsx
│   │   ├── Footer.jsx
│   │   └── Card.jsx
│   ├── data/
│   │   └── posts.js
│   ├── App.jsx
│   └── index.js
├── public/
│   └── styles.css
├── index.html
├── package.json
├── vite.config.js
├── tailwind.config.js
└── dashund.config.js

🛠️ API

Dashund Class

const app = new Dashund(config);

Config Options:

{
  baseUrl: 'https://meusite.com',  // URL base do site
  scrollToTop: true                 // Scroll to top na navegação
}

Métodos

app.route(path, Component, seoMeta)

Define uma rota na aplicação.

app.route('/sobre', About, {
  title: 'Sobre - Meu Site',
  description: 'Saiba mais sobre nós',
  keywords: 'sobre, empresa, missão',
  image: '/og-about.jpg',
  structuredData: {
    "@context": "https://schema.org",
    "@type": "Organization",
    "name": "Minha Empresa"
  }
});

Rotas Dinâmicas:

app.route('/blog/:id', BlogPost, {
  title: 'Blog Post',
  description: 'Leia nossos artigos'
});

app.route('/produtos/:categoria/:id', Product);

app.init(rootId)

Inicializa a aplicação.

app.init('root'); // Monta no elemento #root

app.navigate(path)

Navegação programática.

app.navigate('/blog/1');

🎣 Hooks

useSEO(seoMeta)

Atualiza meta tags dinamicamente.

import { useSEO } from '@dashund/core';

function BlogPost({ params }) {
  const post = getPostById(params.id);
  
  useSEO({
    title: `${post.title} | Meu Blog`,
    description: post.excerpt,
    image: post.image,
    keywords: post.tags.join(', '),
    structuredData: {
      "@context": "https://schema.org",
      "@type": "BlogPosting",
      "headline": post.title,
      "author": post.author,
      "datePublished": post.date
    }
  });

  return <div>{post.content}</div>;
}

useParams()

Acessa parâmetros da rota.

import { useParams } from '@dashund/core';

function BlogPost() {
  const { id } = useParams(); // /blog/:id
  return <h1>Post ID: {id}</h1>;
}

useNavigate()

Hook para navegação.

import { useNavigate } from '@dashund/core';

function Header() {
  const navigate = useNavigate();
  
  return (
    <button onClick={() => navigate('/blog')}>
      Ver Blog
    </button>
  );
}

⚙️ Configuração SEO

dashund.config.js

module.exports = {
  global: {
    siteName: 'Meu Site',
    baseUrl: 'https://meusite.com',
    lang: 'pt-BR',
    favicon: '/favicon.ico',
    css: '/styles.css',
    bundle: '/bundle.js',
    defaultImage: '/og-default.jpg'
  },
  routes: {
    '/': {
      seo: {
        title: 'Home - Meu Site',
        description: 'Site incrível com SEO perfeito',
        keywords: 'react, seo, framework',
        image: '/og-home.jpg',
        structuredData: {
          "@context": "https://schema.org",
          "@type": "WebSite",
          "name": "Meu Site",
          "url": "https://meusite.com"
        }
      }
    },
    '/blog': {
      seo: {
        title: 'Blog - Todos os Artigos',
        description: 'Artigos sobre tecnologia',
        keywords: 'blog, artigos, tecnologia'
      }
    }
  },
  publicDir: 'public'
};

🎨 Integração com Tailwind CSS

O template vem com Tailwind CSS pré-configurado:

tailwind.config.js:

export default {
  content: [
    "./index.html",
    "./src/**/*.{js,jsx}",
  ],
  theme: {
    extend: {
      colors: {
        primary: {
          500: '#667eea',
          600: '#5568d3',
        }
      }
    },
  },
  plugins: [],
}

public/styles.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .btn-primary {
    @apply bg-primary-500 hover:bg-primary-600 
           text-white font-semibold py-3 px-8 rounded-lg;
  }
}

🏗️ Build de Produção

npm run build

O que é gerado:

dist/
├── index.html              # Home com meta tags completas
├── blog/
│   ├── index.html          # Blog listing
│   ├── 1/index.html        # Post 1 com SEO específico
│   ├── 2/index.html        # Post 2 com SEO específico
│   └── 3/index.html        # Post 3 com SEO específico
├── about/index.html        # About page
└── assets/
    ├── bundle.js           # JavaScript otimizado
    └── styles.css          # CSS otimizado

Cada HTML inclui:

  • ✅ Meta tags (<title>, <meta name="description">)
  • ✅ Open Graph tags (og:title, og:description, og:image)
  • ✅ Twitter Cards (twitter:card, twitter:title)
  • ✅ JSON-LD structured data
  • ✅ Canonical URLs
  • ✅ Assets otimizados

🌐 Deploy

Netlify

npm run build
# Deploy a pasta dist/

netlify.toml:

[build]
  command = "npm run build"
  publish = "dist"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Vercel

npm run build
# Deploy a pasta dist/

vercel.json:

{
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "routes": [
    { "handle": "filesystem" },
    { "src": "/(.*)", "dest": "/index.html" }
  ]
}

Cloudflare Pages

npm run build
# Deploy a pasta dist/

Configurações:

  • Build command: npm run build
  • Output directory: dist

🧪 Desenvolvimento Local

Testar o Framework Localmente

# No diretório do framework
npm install
npm run build
npm link

# Criar projeto de teste
dashund create teste-local
cd teste-local
npm link dashund
npm run dev

Scripts Disponíveis

No framework:

npm run build      # Build do framework
npm run dev        # Watch mode (Rollup)
npm test           # Executar testes

No projeto gerado:

npm run dev        # Servidor de desenvolvimento (Vite)
npm run build      # Build de produção
npm run preview    # Preview do build

📊 Comparação

| Feature | Dashund | Next.js | Create React App | |---------|---------|---------|------------------| | Tamanho | ~5kb | ~80kb | ~45kb | | SSR | ❌ (SSG) | ✅ | ❌ | | SEO | ✅ Automático | ✅ | ❌ | | Servidor | ❌ | ✅ Necessário | ❌ | | Deploy | Qualquer CDN | Vercel/Node | Qualquer CDN | | Complexidade | 🟢 Baixa | 🟡 Média | 🟢 Baixa | | Learning Curve | 🟢 Suave | 🟡 Íngreme | 🟢 Suave |


🛠️ Comandos CLI

# Criar novo projeto
dashund create <nome-projeto> [--template <template>]

# Build com SEO
dashund build [--config dashund.config.js] [--output dist]

# Ver versão
dashund --version

# Ajuda
dashund --help

📚 Exemplos

Blog Completo

// src/App.jsx
import Dashund from '@dashund/core';
import Home from './pages/Home';
import Blog from './pages/Blog';
import BlogPost from './pages/BlogPost';

const app = new Dashund({
  baseUrl: 'https://meublog.com'
});

app.route('/', Home, {
  title: 'Home - Meu Blog',
  description: 'Blog sobre tecnologia'
});

app.route('/blog', Blog);
app.route('/blog/:id', BlogPost);

export default app;
// src/pages/BlogPost.jsx
import { useParams, useSEO } from '@dashund/core';
import { getPostById } from '../data/posts';

export default function BlogPost() {
  const { id } = useParams();
  const post = getPostById(id);

  useSEO({
    title: `${post.title} | Meu Blog`,
    description: post.excerpt,
    image: post.image
  });

  return (
    <article>
      <h1>{post.title}</h1>
      <div>{post.content}</div>
    </article>
  );
}

🤝 Contributing

Contribuições são bem-vindas! Por favor, leia nosso guia de contribuição antes de enviar PRs.

Desenvolvimento

# Clone o repositório
git clone https://github.com/yourusername/dashund.git
cd dashund

# Instalar dependências
npm install

# Build
npm run build

# Testar localmente
npm link
dashund create teste
cd teste
npm link @dashund/core
npm run dev

📄 Licença

MIT © 2025


🙏 Agradecimentos

Inspirado pela necessidade de uma solução simples para SEO no React, sem a complexidade do SSR.


📞 Suporte


Feito com ❤️ e 🐕

"O doguinho que corre atrás do SEO que o React esqueceu."