# Project Setup and the supabase-js Client — Supabase

Source: https://www.skillbyai.com/en/supabase/f-client

> Create a project and connect from code.

## One client per context

Create a project in the dashboard (or locally with the CLI), then install **@supabase/supabase-js**. `createClient(url, key)` returns a client exposing `from()` for tables, `rpc()` for functions, `auth`, `storage`, `functions` and `channel()` for realtime. In a browser app create **one** shared client and reuse it. Every call returns an object with `data` and `error` rather than throwing, so always check `error`.

## Creating and using the client

supabase-js v2.

```typescript
import { createClient } from '@supabase/supabase-js'

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

const { data, error } = await supabase.from('todos').select('id, title, done')
if (error) {
  console.error(error.message)
} else {
  console.log(data)
}
```

## Check error, not try/catch

supabase-js returns `{ data, error }`; a failed query does not throw by default, so unchecked errors fail silently.

**Quiz:** How does a supabase-js query report a failure?

- [ ] It logs and retries forever
- [ ] It always throws an exception
- [ ] It returns HTTP 500 to the user
- [x] It returns an error object alongside data

*Answer:* It returns an error object alongside data. Destructure { data, error } and check error.
