JIRA comes with many options to change the look and feel of features in the system. User formats are a feature that can be customised by plugins. You can write your own User Format plugin to change the display of user details in JIRA, e.g. display a profile picture. See the User Format Plugin Module for more information.
JIRA comes with various reports built-in. Using the plugin system, new reports can be written, providing new ways of viewing and summarising JIRA's data.
Workflow functions and conditions
JIRA's issue workflow (states and state transitions an issue can go through) can be customized through the web interface (see the workflow documentation. The workflow engine (OSWorkflow) provides hooks where you can plug in your own behaviour:
Run arbitrary Java when a certain transition occurs, via post-functions
Limit visibility of transitions to certain users, via conditions
By writing a plugin, you can add new issue or project tab panels to JIRA. For instance, you may wish to display project/issue data pulled in from an external source. This is how the JIRA Subversion plugin works. See the plugin guide for more information on writing these plugin types.
JIRA has a complete event subsystem which fires events whenever anything happens. For example an ISSUE_CREATED event is fired whenever an issue is created. A listener is just a class which implements a JiraListener interface and is called whenever events occur in JIRA. Using those events, you can then perform any action you want. For example the email sent by JIRA is driven by the MailListener. This is useful when you want to drive or affect external systems from events which occur within JIRA - usually used to push data into outside systems. For more information, read the listeners documentation.
Services are classes which implement the JiraService interface. When installed, you specify an update period and JIRA will call the run() method of your service periodically. A sample service is provided called POPCommentService. This service checks a particular POP mailbox periodically and if it finds messages, tries to extract an issue key from the subject. If the subject contains a key, the body of the mail is added as a comment to the message. Services are useful when you want to periodically pull data into JIRA from outside systems. For more information, see the services guide.
JIRA has a full set of Java APIs that can be used to update information with in JIRA. You can view the API here. JIRA commercial customers get full access to the JIRA source (see bottom of the downloads page), so you can modify JIRA itself if necessary. See the Building JIRA from Source page for more information.