> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/jitsi/lib-jitsi-meet/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Create your first Jitsi Meet video conference with lib-jitsi-meet

# Quick Start Guide

This guide walks you through creating a basic video conference using lib-jitsi-meet. You'll learn the essential steps: initialization, creating local tracks, connecting to a server, and joining a conference.

## Prerequisites

* lib-jitsi-meet installed ([Installation Guide](/installation))
* A Jitsi Meet deployment or JaaS (Jitsi as a Service) account
* Modern browser with WebRTC support

## Basic Conference Flow

The typical flow for creating a conference:

<Steps>
  <Step title="Initialize JitsiMeetJS">
    Call `init()` before using any other library functions:

    ```javascript theme={null}
    import JitsiMeetJS from 'lib-jitsi-meet';

    // Initialize with options
    JitsiMeetJS.init({
      enableAnalyticsLogging: false,
      disableAudioLevels: false,
      disableThirdPartyRequests: false,
    });
    ```

    Available initialization options (from `JitsiMeetJS.ts:89-106`):

    ```typescript theme={null}
    interface IJitsiMeetJSOptions {
      analytics?: {
        rtcstatsLogFlushSizeBytes?: number;
        rtcstatsStoreLogs?: boolean;
      };
      audioLevelsInterval?: number;
      desktopSharingSources?: Array<'screen' | 'window'>;
      disableAudioLevels?: boolean;
      disableThirdPartyRequests?: boolean;
      enableAnalyticsLogging?: boolean;
      enableWindowOnErrorHandler?: boolean;
      externalStorage?: Storage;
      flags?: {
        runInLiteMode?: boolean;
        ssrcRewritingEnabled?: boolean;
      };
      pcStatsInterval?: number;
    }
    ```
  </Step>

  <Step title="Create Local Tracks">
    Request access to camera and microphone:

    ```javascript theme={null}
    // Create audio and video tracks
    const tracks = await JitsiMeetJS.createLocalTracks({
      devices: ['audio', 'video'],
      resolution: '720',
      constraints: {
        video: {
          height: { ideal: 720, max: 720, min: 180 },
          width: { ideal: 1280, max: 1280, min: 320 }
        }
      }
    });

    // Attach tracks to DOM elements
    tracks.forEach(track => {
      if (track.getType() === 'video') {
        const videoElement = document.getElementById('localVideo');
        track.attach(videoElement);
      } else {
        const audioElement = document.getElementById('localAudio');
        track.attach(audioElement);
      }
    });
    ```

    Options for `createLocalTracks()` (from `JitsiMeetJS.ts:79-85`):

    ```typescript theme={null}
    interface ICreateLocalTrackOptions {
      cameraDeviceId?: string;      // Specific camera device ID
      devices?: any[];              // Array of 'audio', 'video', 'desktop'
      fireSlowPromiseEvent?: boolean;
      micDeviceId?: string;         // Specific microphone device ID
      resolution?: string;          // '720', '1080', etc.
    }
    ```
  </Step>

  <Step title="Create JitsiConnection">
    Establish a connection to the Jitsi Meet server:

    ```javascript theme={null}
    import { JitsiConnectionEvents } from 'lib-jitsi-meet/JitsiConnectionEvents';

    const connection = new JitsiMeetJS.JitsiConnection(
      null,  // appId (optional for self-hosted)
      null,  // token (JWT for authentication)
      {
        hosts: {
          domain: 'meet.jit.si',
          muc: 'conference.meet.jit.si'
        },
        serviceUrl: 'wss://meet.jit.si/xmpp-websocket',
        enableWebsocketResume: true
      }
    );

    // Handle connection events
    connection.addEventListener(
      JitsiConnectionEvents.CONNECTION_ESTABLISHED,
      onConnectionSuccess
    );

    connection.addEventListener(
      JitsiConnectionEvents.CONNECTION_FAILED,
      onConnectionFailed
    );

    connection.addEventListener(
      JitsiConnectionEvents.CONNECTION_DISCONNECTED,
      onDisconnected
    );

    // Connect
    connection.connect();
    ```

    Connection options (from `JitsiConnection.ts:16-34`):

    ```typescript theme={null}
    interface IConnectionOptions {
      hosts: {
        domain: string;           // XMPP domain
        muc?: string;            // Multi-user chat domain
      };
      serviceUrl: string;         // WebSocket URL
      enableWebsocketResume: boolean;
      websocketKeepAlive?: number;
      websocketKeepAliveUrl?: string;
      p2pStunServers?: any[];
    }
    ```
  </Step>

  <Step title="Initialize and Join Conference">
    Once connected, create and join a conference:

    ```javascript theme={null}
    import { JitsiConferenceEvents } from 'lib-jitsi-meet/JitsiConferenceEvents';

    function onConnectionSuccess() {
      // Create conference
      const conference = connection.initJitsiConference('my-room-name', {
        openBridgeChannel: true,
        p2p: {
          enabled: true,
          preferredCodec: 'VP9'
        }
      });
      
      // Add local tracks
      tracks.forEach(track => conference.addTrack(track));
      
      // Handle conference events
      conference.on(JitsiConferenceEvents.TRACK_ADDED, onRemoteTrack);
      conference.on(JitsiConferenceEvents.TRACK_REMOVED, onTrackRemoved);
      conference.on(JitsiConferenceEvents.USER_JOINED, onUserJoined);
      conference.on(JitsiConferenceEvents.USER_LEFT, onUserLeft);
      conference.on(JitsiConferenceEvents.CONFERENCE_JOINED, onConferenceJoined);
      
      // Join the conference
      conference.join();
    }

    function onConferenceJoined() {
      console.log('Successfully joined conference!');
    }
    ```
  </Step>

  <Step title="Handle Remote Tracks">
    Display remote participant media:

    ```javascript theme={null}
    import { JitsiTrackEvents } from 'lib-jitsi-meet/JitsiTrackEvents';

    function onRemoteTrack(track) {
      if (track.isLocal()) return;
      
      const participantId = track.getParticipantId();
      
      // Create container for remote participant
      if (!document.getElementById(participantId)) {
        const container = document.createElement('div');
        container.id = participantId;
        document.getElementById('remoteVideos').appendChild(container);
      }
      
      // Attach the track
      if (track.getType() === 'video') {
        const video = document.createElement('video');
        video.autoplay = true;
        video.id = `${participantId}-video`;
        document.getElementById(participantId).appendChild(video);
        track.attach(video);
      } else {
        const audio = document.createElement('audio');
        audio.autoplay = true;
        audio.id = `${participantId}-audio`;
        document.getElementById(participantId).appendChild(audio);
        track.attach(audio);
      }
    }

    function onTrackRemoved(track) {
      if (track.isLocal()) return;
      
      const id = track.getType() === 'video' 
        ? `${track.getParticipantId()}-video`
        : `${track.getParticipantId()}-audio`;
      
      const element = document.getElementById(id);
      if (element) {
        element.remove();
      }
    }
    ```
  </Step>
</Steps>

## Complete Example

Here's a complete working example:

```javascript theme={null}
import JitsiMeetJS from 'lib-jitsi-meet';
import { JitsiConnectionEvents } from 'lib-jitsi-meet/JitsiConnectionEvents';
import { JitsiConferenceEvents } from 'lib-jitsi-meet/JitsiConferenceEvents';

let connection = null;
let conference = null;
let localTracks = [];

// Initialize
JitsiMeetJS.init();

// Set log level (optional)
JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);

async function joinConference(roomName) {
  try {
    // Create local tracks
    localTracks = await JitsiMeetJS.createLocalTracks({
      devices: ['audio', 'video']
    });
    
    // Attach local tracks to DOM
    localTracks.forEach(track => {
      if (track.getType() === 'video') {
        track.attach(document.getElementById('localVideo'));
      }
    });
    
    // Create connection
    connection = new JitsiMeetJS.JitsiConnection(null, null, {
      hosts: {
        domain: 'meet.jit.si',
        muc: 'conference.meet.jit.si'
      },
      serviceUrl: 'wss://meet.jit.si/xmpp-websocket',
      enableWebsocketResume: true
    });
    
    // Connection event handlers
    connection.addEventListener(
      JitsiConnectionEvents.CONNECTION_ESTABLISHED,
      () => onConnectionEstablished(roomName)
    );
    
    connection.addEventListener(
      JitsiConnectionEvents.CONNECTION_FAILED,
      (error) => console.error('Connection failed:', error)
    );
    
    // Connect
    connection.connect();
    
  } catch (error) {
    console.error('Error joining conference:', error);
  }
}

function onConnectionEstablished(roomName) {
  // Initialize conference
  conference = connection.initJitsiConference(roomName, {
    openBridgeChannel: true
  });
  
  // Conference event handlers
  conference.on(JitsiConferenceEvents.CONFERENCE_JOINED, () => {
    console.log('Conference joined!');
  });
  
  conference.on(JitsiConferenceEvents.TRACK_ADDED, (track) => {
    if (!track.isLocal()) {
      const participantId = track.getParticipantId();
      const element = track.getType() === 'video' 
        ? document.getElementById(`remote-video-${participantId}`)
        : document.getElementById(`remote-audio-${participantId}`);
      
      if (element) {
        track.attach(element);
      }
    }
  });
  
  conference.on(JitsiConferenceEvents.USER_JOINED, (id, user) => {
    console.log('User joined:', id);
  });
  
  conference.on(JitsiConferenceEvents.USER_LEFT, (id) => {
    console.log('User left:', id);
  });
  
  // Add local tracks
  localTracks.forEach(track => conference.addTrack(track));
  
  // Join conference
  conference.join();
}

// Usage
joinConference('my-test-room');
```

## Simplified API with joinConference()

For JaaS users, lib-jitsi-meet provides a simplified `joinConference()` method that handles everything automatically (from `JitsiMeetJS.ts:448-526`):

```javascript theme={null}
// Simple JaaS conference join
const conference = await JitsiMeetJS.joinConference(
  'my-room-name',
  'vpaas-magic-cookie-1234567890abcdef',  // JaaS app ID
  'your-jwt-token',
  {
    tracks: localTracks,  // Optional: pre-created tracks
    conferenceOptions: {
      openBridgeChannel: true
    }
  }
);

// Conference is ready to use
conference.on(JitsiConferenceEvents.USER_JOINED, (id) => {
  console.log('User joined:', id);
});
```

This method automatically:

* Configures JaaS endpoints and domains
* Creates the connection
* Initializes the conference
* Adds tracks and joins
* Sets up receiver constraints

## Event Handling Reference

Key events you'll commonly handle:

**Connection Events** (from `JitsiConnectionEvents`)

* `CONNECTION_ESTABLISHED` - Connected to server
* `CONNECTION_FAILED` - Connection failed
* `CONNECTION_DISCONNECTED` - Disconnected from server

**Conference Events** (from `JitsiConferenceEvents`)

* `CONFERENCE_JOINED` - Successfully joined conference
* `CONFERENCE_LEFT` - Left the conference
* `USER_JOINED` - Remote participant joined
* `USER_LEFT` - Remote participant left
* `TRACK_ADDED` - Media track added (local or remote)
* `TRACK_REMOVED` - Media track removed
* `TRACK_MUTE_CHANGED` - Track mute status changed
* `DISPLAY_NAME_CHANGED` - Participant display name changed
* `DOMINANT_SPEAKER_CHANGED` - Active speaker changed

**Track Events** (from `JitsiTrackEvents`)

* `TRACK_AUDIO_LEVEL_CHANGED` - Audio level changed
* `TRACK_MUTE_CHANGED` - Mute status changed
* `LOCAL_TRACK_STOPPED` - Local track stopped
* `NO_DATA_FROM_SOURCE` - No data from media source

## Next Steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="book" href="/api/jitsi-meet-js">
    Explore the complete API documentation
  </Card>

  <Card title="Advanced Features" icon="wand-magic-sparkles" href="/advanced/webrtc-internals">
    Learn about E2EE, screen sharing, and quality control
  </Card>
</CardGroup>
